Reputation: 9
I am trying to read and write a text document and then perform operations on it.
#include<stdio.h>
#include<string.h>
int WRITE(char *FILENAME, char *DATA)
{
FILE *ptr_file;
ptr_file =fopen(FILENAME, "w");
if (!ptr_file)
return 1;
fprintf(ptr_file,"%s", DATA);
fclose(ptr_file);
return 0;
}
char READ(char *FILENAME)
{
FILE *ptr_file;
char buf[1000];
char* ret="";
ptr_file =fopen(FILENAME,"r");
if (!ptr_file)
return "FAIL\n";
while (fgets(buf,1000, ptr_file)!=NULL)
ret=strcat("%s",ret);
fclose(ptr_file);
return ret;
}
int main()
{
char* DAT = "lol";
char* FILENAME = "output.txt";
char* NEWDAT;
int count=0;
int max=10;
while (count<max) {
NEWDAT=READ(FILENAME);
WRITE(FILENAME,strcat(DAT,NEWDAT));
count++;
}
READ(FILENAME);
return 0;
}
This is what the compiler says
gcc -Wall -o "filewrite" "filewrite.c" (in directory: /home/x/Documents/programming/C code)
filewrite.c: In function ‘READ’:
filewrite.c:22:3: warning: return makes integer from pointer without a cast [enabled by default]
filewrite.c:26:2: warning: return makes integer from pointer without a cast [enabled by default]
filewrite.c: In function ‘main’:
filewrite.c:38:9: warning: assignment makes pointer from integer without a cast [enabled by default]
Compilation finished successfully.
Then it throws me a Code 139/Segmentation Fault. I... seriously cannot begin to understand what's going on here; at the level i am at.
#POST-ANSWERS EDIT: FIXED CODE WORKING
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // malloc
int WRITE(char *FILENAME, char *DATA)
{
FILE *ptr_file;
ptr_file =fopen(FILENAME, "w");
if (!ptr_file)
return 1;
fprintf(ptr_file,"%s", DATA);
fclose(ptr_file);
return 0;
}
char* READ(char *FILENAME)
{
FILE *ptr_file;
char buf[1000];
char *ret = malloc(1);
int retsize = 1;
ret[0]='\0';
buf[0]='\0';
ptr_file = fopen(FILENAME,"r");
if (!ptr_file) {
ret = realloc(ret, strlen("FAIL\n") + 1);
strcpy(ret, "FAIL\n");
return ret;
}
while (fgets(buf,1000, ptr_file)!=NULL)
{
retsize += strlen(buf)+1; // new size is old size + length of string in buf
ret = realloc(ret, retsize); // increase the size of the allocation
strcat(ret, buf); // append the new data
}
fclose(ptr_file);
return ret;
}
int main()
{
char* DAT = malloc(1);
int datsize = 1;
char* FILENAME = "output.txt";
char* NEWDAT;
strcpy(DAT, "LOL");
int count=0;
int max=5;
while (count<max) {
NEWDAT=READ(FILENAME);
datsize += strlen(NEWDAT) + strlen(DAT);
DAT = realloc(DAT, datsize);
strcat(DAT,NEWDAT);
WRITE(FILENAME,DAT);
printf("%i\n",count);
printf("%s\n",DAT);
count++;
}
READ(FILENAME);
return 0;
}
Upvotes: 1
Views: 3059
Reputation: 19504
This is the big problem I see.
char* ret="";
...
ret=strcat("%s",ret);
For one, strcat
doesn't take a format specification (maybe you're thinking of sprintf
).
For two, you cannot modify the contents of a string literal (like "%s"
or ""
). You have to allocate space or use a character array like you did with buf
.
If you want to return the accumulated contents of buf
, try
char *ret = malloc(1);
int retsize = 1;
ret[0] = '\0'; // this line could also be written: `strcpy(ret,"");` or `*ret = 0;`
...
while (fgets(buf,1000, ptr_file)!=NULL)
{
retsize += strlen(buf)+1; // new size is old size + length of string in buf
ret = realloc(ret, retsize); // increase the size of the allocation
strcat(ret, buf); // append the new data
}
To remove the compiler warnings, add
#include <stdlib.h> // malloc
And, as others have said. The return type of the function should be char *
to match the variable whose value is being returned.
Addressing the edited code.
NEWDAT is receiving the data read by READ. So it's DAT that needs to be resizable.
...
char* DAT = malloc(1);
int datsize = 1;
char* FILENAME = "output.txt";
char* NEWDAT;
DAT[0]='\0';
int count=0;
int max=5;
while (count<max) {
NEWDAT=READ(FILENAME);
datsize += strlen(NEWDAT) + 1;
DAT = realloc(DAT, datsize);
strcat(DAT,NEWDAT);
WRITE(FILENAME,NEWDAT);
...
As BrainSteel points out, there is another issue with the READ function, although it's not critical for getting this program to run.
if (!ptr_file)
return "FAIL\n";
Since one path returns this string literal, and the other path returns malloc
ed data, the calling function won't know whether to call free
or not. We can fix this by always returning malloc
ed memory.
if (!ptr_file) {
ret = realloc(ret, strlen("FAIL\n") + 1);
strcpy(ret, "FAIL\n");
return ret;
}
Upvotes: 2
Reputation: 29266
READ
(horrible naming convention BTW) claims to return a char
, but your code is acting like it's char*
The strcat("%s", ret)
is bad beacuse the destination ("%s") doesn't have any space to append "ret")
Upvotes: 5