Segmentation fault strcpy/strcat - c

I am writing a program to open a file (say "input_file"), manipulate its contents and then output it to another file ("manipulated-input_file")
I have done this with strcpy and strcat in the following way:
char t-filename[]="Manipulated-", filename[50], td-filename[50];
memset ( filename, '\0', FILE_NAME);
printf("Please enter the filename - \n");
scanf( "%30s", filename );
strcpy(td-filename,filename);
strcat(t-filename,td-filename);
printf("%s\n", t-filename);
Now printf functions prints the t-filename as "Manipulated-input_file"
After this part, I have a section where I open "input_file" and
do something.
fptr = fopen(filename, "r");
while ( fgets (line, sizeof line, fptr) != NULL)
{
...do something...
}
fclose(fptr);
Later I wanted to open a file with name 't-filename' at the end of the code:
tptr = fopen(t-filename, "w");
fprintf(tptr,"something");
fclose(tpr);
When I compile this code I am getting "Segmentation fault (core dumped)".
I do not know what went wrong. Can somebody help?

transfilename doesn't have enough space to hold additional items added there by strcat(transfilename,translatedfilename);. It's already full with "Translated-" since [] gives you the exact amount of characters in the initializing string, plus a null terminator.
You need to either change it to char transfilename [LARGE_ENOUGH] or use dynamic memory allocation to change the size in run-time.

strcat(t-filename,td-filename);
t-filename is not large enough to accommodate the result and it is an Undefined Behaviour.
same here
strcat(transfilename,translatedfilename);
transfilename is not large enough to accommodate the result and it is an Undefined Behaviour.

Related

Getting the Contents of a File and Putting it into a String in C

I am trying to make a function in C that takes the contents of a file and returns the contents as a string. I got it to works except for one odd detail. This is the current code:
char *getFileContents(const char *filePath) {
if (filePath == NULL) return NULL;
char buffer[1000];
char character;
int count = 0;
FILE *f = fopen(filePath, "r");
while (character != EOF) {
count++;
character = fgetc(f);
printf("%c\n", character);
}
count--;
fclose(f);
FILE *F = fopen(filePath, "r");
char *str = (char*) malloc ( sizeof(char) * (count + 1 ) );
char *line = fgets(buffer, 1000, F);
while (line != NULL) {
strcat(str, line);
line = fgets(buffer, 1000, F);
}
fclose(F);
return str;
}
In the first while loop, I added a printf statement for error checking that I do not need anymore. The function works fine with the printf statement but whenever I comment it out or remove it I get a segmentation fault. I've used gdb to debug and try to find the issue.
I can step through the whole function but the moment it reaches the return str at the end I get a segmentation fault. I'm not sure why I'm experiencing this problem.
One problem is that you never initialize the memory buffer returned by malloc() -- you are apparently expecting it to be all-zeros (or at least start with a 0-byte) so that you can fill it in with calls to strcat(); but malloc() doesn't guarantee the contents of the memory it returns will be zeroed-out, so you are likely starting with some garbage-bytes already present in the str buffer, which means that as you add more bytes from the file, you will likely write past the end of the buffer and invoke undefined behavior (and likely crash).
The simple fix would be to do a str[0] = '\0'; after the call to malloc() (or if you're paranoid, you could do a full memset(str, 0, count+1);). Or alternatively you could allocate the memory with a call to calloc() rather than malloc(), as calloc() does guarantee that the returned buffer will be all zero-initialized bytes.
The commenting of a line causing a segmentation fault is the manifestation of Undefined Behaviour.
The initial comparison of character with EOF reads an uninitialized, garbage value.
char character;
/* ... */
while (character != EOF) {
/* ... */
The results of this program cannot be reasoned about after this occurs. A random SIGSEGV is par for the course.
Additionally, fgetc returns an int. EOF is a negative value, and cannot be properly represented if char is unsigned.
Try changing your loop construct.
int character;
/* ... */
while (EOF != (character = fgetc(f))
count++;
Note, you should also check that the return value from fopen was not NULL, and react accordingly.
FILE *f = fopen(filePath, "r");
if (!f) {
perror(filePath);
return NULL;
}
I got rid of the first while loop that counts the number of characters in the file and moved it to a different function. The function I moved it to will be responsible for counting the characters. This way I would only need one fopen and fclose statement in the getFileContents function. This solved my problem and everything is working as intended.

C program to read a text file line by line then print out those lines to the terminal

I want to have a c program read a text file line by line then print out those lines to the terminal.
My code
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* line;
FILE *ifp;
ifp = fopen("BBE.txt", "r");
if (ifp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
while (fscanf(ifp, "%s", line) == 1)
{
printf("%s\n", line);
}
fclose(ifp);
return 0;
}
The program when i try to run it does not print out anything to the terminal. This tells me that the while loop is not working but i am not to sure as to why.
Your loop is not working, because fscanf does not return just 1 on success.
According to the man page of fscanf, the return value has the following meaning:
RETURN VALUE
On success, these functions return the number of input items
successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set to indicate the error.
Additionally as already stated in another answer: You write to memory that is NOT YOUR memory:
char* line;
is just a the declaration of a pointer to a char. What you need is a contiguous array of char to write to.
You either can allocate this on the stack by declaring it:
char line[1000]; // Allocate a char array of the size of 1000.
or on the heap;
char* line = malloc(1000*sizeof(char)); // Allocate 1000 chars on the heap
here you have to free the memory afterwards
free(line);
You used *line without initialising it -> undefined behavior.
To fix that, you can use a char array instead:
char line[1000] = "";

Reading from file into array, line by line

I am trying to read from a file in C. My code is the following. It seems to read everything fine into the array, but when I try to print it, I get the error Segmentation fault (core dumped)
FILE *fp;
char * text[7][100];
int i=0;
fp = fopen("userList.txt", "r");
//Read over file contents until either EOF is reached or maximum characters is read and store in character array
while(fgets((*text)[i++],100,fp) != NULL) ;
printf("%s", &text[0]);
fclose(fp);
Can someone point me in the right direction?
I have tried reading and copying solutions from other similar cases, but they are extremely specific to the user.
So part one, you don't need a pointer to a char[][]:
char text[7][100];
Part 2, just deference your array of strings like a normal person, nothing fancy here:
while(fgets((text)[i++],100,fp) != NULL) ;
Live example: http://ideone.com/MADAAs
Some things to watch out for:
If your input file has more than 7 lines you are going to have problems.
Why is “while ( !feof (file) )” always wrong?
char * text[7][100]; //wrong - this is 2 diminutions array of char pointers, replace it with
char text[7][100];
while(fgets((*text)[i++],100,fp) != NULL) ; // replace this with
while(fgets(&text[i++][0],100,fp) != NULL) ;
NOTE: this code will work in the current scope of the function (on the stack) if you need to use it outside the scope of current scope , allocate some memory on the heap and use the pointers of the heap.

Reading a file using fgets and printing its content on screen

I still consider myself as a new webby in C.I am trying to read a file in, file is not binary but its size varies from small size of feb kbs to big size files of feb Mbs.I am using fgets function, i had taken reference from this link but after compilation, i am getting segmentation fault.i tried to debug it with gdb and found that i am able to open file but unable to read.Here is my code.
#include<stdio.h>
#define MAX_LENGTH 1048576
int main()
{
FILE *fp;
char *result;
char line[MAX_LENGTH];
fp =fopen("/home/shailendra/sampleprograms/C/shail1.txt","r");
if(result=fgets(line,MAX_LENGTH,fp) != NULL)
printf("The string is %s \n",result);
else
printf("Error opening the file");
if(fclose(fp))
printf("fclose error");
}
This Segmentation fault really sucks your blood.I understand that it is due to insufficient memory allocation but i had used MAX_LENGTH 1048576, so i don't think that it must create any problem.I had tried it with both small files with only one line and a big file with multiple lines but i am unable to figure out why i am getting segmentation fault.
I also looked at this and this but got no help.
Try some parentheses:
if((result=fgets(line,MAX_LENGTH,fp)) != NULL)
^ ^
Without those you'll store the result of the comparison instead of a pointer to the string.
Side note: you don't need result at all. When it succeeds, fgets returns the pointer you passed in; in other words you can just printf line:
if(fgets(line, MAX_LENGTH, fp))
printf("The string is %s \n", line);
Second side note: before trying to fgets from the file, you should check whether fopen succeeded:
if (!fp)
perror("fopen");
Couple of things in addition to cnicutar's answer:
#include <stdio.h>
^ Please make sure you have a space between your includes and the headers
fgets will read until it's encountered a new line or EOF (whichever comes first), so to read the whole file you'd have to do it in a loop.
I would recommend doing it like this (no need for the pointer assignment as pointed out):
while(fgets(line, MAX_LENGTH, fp))
printf("%s", line);

segmentation fault on reading in a data file

I am trying to read in a file of characters into an array of 64 characters. the file reading happens in main()
int main (int argc, char **argv)
{
FILE *fp;
char write_msg[BUFFER_SIZE];
fp = fopen("test.data", "r");
int i;
for ( i = 0; i < (BUFFER_SIZE-1); i++){
fscanf(fp, "%s\n", &write_msg[i]);
printf ("printing in the for loop");
}
fclose(fp);
printf("Starting the main().\n");
printf("in Reader, the msg is: %s\n",write_msg);
pid_t pid;
int fd[2];
I keep getting a seg fault and I am not sure what I am doing
fscanf(fp, "%s\n", &write_msg[i]); should be fscanf(fp, "%c\n", &write_msg[i]);, you don't want to scan a string into a char.
And the write_msg should ends with a '\0', write_msg[BUFFER_SIZE-1]=0
I see the following problem in your code:
fscanf(fp, "%s\n", &write_msg[i]);
You are attempting to read a string starting at position i that is moving within your loop. It will be very easy to get a segmentation fault when i reaches the end of the memory reserved for the string write_msg.
Another recommendation: Put a validation on your fp descriptor:
fp = fopen("test.data", "r");
if ( fp == NULL ) {
/* Show an error and exit */
}
If for any reason the file could not be read, fp will be NULL and as segmentation fault would be raised.
You're scanning a string, which might be rather long, into a buffer without limiting how many characters will be read. You shouldn't do that. You're then incrementing i by one, even though the string might be much longer. You should use fgets or fread to read the entire file into your buffer, since you really don't need the special features of fscanf, and those functions will take a length of characters to read. Or if you really really like your for loop, you could use fgetc, which does exactly what you think fscanf is doing.

Resources