Segmentation fault block - c

FILE *fp;
fp = fopen(filen, "wb");
const char tok[2] = ",";
char str[340];
while (fgets(str, 340, stdin) != NULL)
{
struct test loadTest;
printf("You entered: %s", str);
strncpy(loadTest.level, strtok(str, tok), 20);
strncpy(loadTest.first, strtok(NULL, tok), 30);
fwrite(&loadTest, sizeof(struct test), 1, fp);
}
fclose(fp);
Hello all,
For some reason I'm getting a segmentation fault error in my code.
I'm almost positive the error is somewhere within the small code block above (since that's all I modified for the seg fault), but I can't seem to pinpoint it.
I know segmentation faults have to do with accessing memory I shouldn't be accessing, but I'm not sure where I am even doing that in the code.
Any help would be greatly appreciated!

Some improvements of your code
check result of fopen before read/write to file
initialize variables before using their values
use sizeof instead of constant (as mentioned in comments)
strtok() can return NULL and this must be checked (see here why)
you must use strncpy() carefully because of this
Here is corrected version of your code
FILE *fp;
fp = fopen(filen, "wb");
if (fp == NULL)
{
printf("Error opening file: %s", filen);
}
else
{
const char tok[2] = ",";
char str[340];
while (fgets(str, sizeof(str), stdin) != NULL)
{
struct test loadTest;
char *level;
char *first;
memset(&loadTest, 0, sizeof(loadTest));
printf("You entered: %s", str);
level = strtok(str, tok);
if (level == NULL)
{
continue; // bad input ?
}
first = strtok(NULL, tok);
if (first == NULL)
{
continue;
}
strncpy(loadTest.level, level, sizeof(loadTest.level)-sizeof(char));
strncpy(loadTest.first, first, sizeof(loadTest.first)-sizeof(char));
fwrite(&loadTest, sizeof(loadTest), 1, fp);
}
fclose(fp);
}

Related

when copying strings from one text file to another, the last line in the original file is not copied

edit: change the code to my real code, because i was told that the shortened one i posted couldn't be compiled. hope it helps in finding the problem
i have a struct as below:
struct patient {
char name[30], ID[8];
int age, phoneNo;
};
and i've written the code below:
int searchName()
{
char search[30];
char record[60];
const char s[2] = ",";
struct patient c;
int foundRecord = 0, linectr = 0;
char a[8], str[200], tempname[] = "tempfile.txt", filename[] = "patient.txt";
int IDno, temp = 999999;
FILE* fPtr, *fPtr2;
fPtr = fopen(filename, "r");
printf("Enter name to to replace phoneNo with 999999: ");
getchar();
fgets(search, 30, stdin);
//remove the '\n' at the end of string
search[strcspn(search, "\n")] = 0;
printf("Record found: ");
while (fgets(record, 60, fPtr))
{
// strstr returns start address of substring in case if present
if (strstr(record, search))
{
char* pStr = strtok(record, ",");
if (pStr != NULL) {
strcpy(c.ID, pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
strcpy(c.name, pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
c.age = atoi(pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
c.phoneNo = atoi(pStr);
}
printf("\n%s\t%s\t%d\t%d", c.ID, c.name, c.age, c.phoneNo);
foundRecord++;
}
}
if (foundRecord = 0)
printf("%s cannot be found\n", search);
strcpy(a, c.ID);
sscanf(a, "PT%d", &IDno);
fPtr = fopen(filename, "r");
fPtr2 = fopen(tempname, "w");
while (!feof(fPtr))
{
strcpy(str, "\0");
fgets(str, 100, fPtr);
if (!feof(fPtr))
{
linectr++;
if (linectr != IDno)
{
fprintf(fPtr2, "%s", str);
}
else
{
fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
}
}
}
fclose(fPtr);
fclose(fPtr2);
remove(filename);
rename(tempname, filename);
printf("\nReplacement successful. \n");
return 0;
}
the code works like this: i have a bunch of strings in a text file called patient.txt, and i want to replace a string (IDno) in the text file with a string i have stored in struct patient c prior to this. the code works in creating another file and copying strings from the original file (patient.txt) into a new file while replacing the original string with the the new string, but i noticed that the last string in the original file always gets ignored. for example, i have 6 lines below stored in the original file:
PT1,John Doe,35,123456
PT2,Mary Ann,34,124684
PT3,John Lemmons,15,834945
PT4,James Bond,22,565453
PT5,Mary Sue,34,3435453
PT6,John Brown,54,3435346
when i search for Mary Ann to be replaced (line 2), only the first 5 lines (including the replaced 2nd line) get copied into the new file when i run my code. why is the last line not being copied? another issue is that the remove and rename functions in my code isn't working and i'm not sure why. would appreciate it if someone could explain how i can fix this.
Using feof is most likely the problem, see Why is “while ( !feof (file) )” always wrong?, you can create a much simpler and effective while cycle using fgets return value as a stop condition:
while (fgets(str, 100, fPtr)) //when file ends stop
{
linectr++;
if (linectr != IDno)
{
fprintf(fPtr2, "%s", str);
}
else
{
fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
}
}
There is also typo in if (foundRecord = 0), it should be ==, that is most certainly derailing your program.
Replace all your while (!feof(fPtr)) loop with this:
while (fgets(str, 100, fPtr) != NULL)
{
linectr++;
if (linectr != IDno)
{
fprintf(fPtr2, "%s", str);
}
else
{
fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
}
}
There may be other problems though.
Off topic remarks:
you should check if fopen fails which actually happens very often in the real world.
drop the [15] in char tempname[15] = "tempfile.txt" -> char tempname[] = "tempfile.txt"

Segmentation fault when reading file in c in a small file

I got segmentation fault ( core dumped) in c while reading a file.i used this code for milion other files and it workes fine. But this file has 138 lines when others start at 250. So im guessing thats the problem? (the code is on the bottom of my post)its suppose to help me work on the read data so i could do operations on them in the code but whatever i do its just "core dumped"
it breaks here :
while (fgets(line, sizeof line, fp) != NULL) {
strtok(line, "\n");
parseLine(line, &dataList);
}
i already tried :
char *line = malloc( sizeof(char) * ( LINE_BUFFER + 1 )
instead of
char line[LINE_BUFFER];
Heres the part of the code that reads a file :
#define DIFF_BUFFER 99999999
DataLineNode *loadData(const char *fileName) {
FILE *fp;
char line[LINE_BUFFER];
DataLineNode *dataList = NULL;
fp = fopen(fileName, "r");
if (fp == NULL) {
printf("No file '%s'.\n", fileName);
exit(EXIT_FAILURE);
}
while (fgets(line, sizeof line, fp) != NULL) {
strtok(line, "\n");
parseLine(line, &dataList);
}
fclose(fp);
return dataList;
}
````

C Why can't my fgets() read line properly when writing with \n after words

This is a bit difficult to articulate but what I would like is for my commented out fprintf function to be commented in and my other two print functions commented out (In my add_to_white_list function).
However, when I write to the file in that way (with the \n after the word) something goes wrong with my fgets line reader in the remove_from_white_list function. In debugging my fgets reads the first line and then seems to be blank after.
This if very confusing to me because everything mostly works as is and there are still newline characters after all my words except for the last word in the file.
void add_to_white_list(char* ip) {
FILE *fp;
fp = fopen("../app/whitelist.txt", "r+");
if (!(getc(fp) < 0)) {
fseek(fp, 1, SEEK_END);
fputs("\n", fp);
}
fprintf(fp, "%s", ip);
//fprintf(fp, "%s\n", ip);
fclose(fp);
}
void remove_from_white_list(char* ip) {
FILE *fp;
FILE *fp_temp;
fp = fopen("../app/whitelist.txt", "r");
fp_temp = fopen("../app/temp.txt", "w+");
char buff[255];
int matched = 0;
while (fgets(buff, 255, fp) != NULL) {
strip(buff);
if (!(strcmp(buff, ip) == 0)) {
fprintf(fp_temp, "%s\n", buff);
} else {
matched = 1;
}
}
fclose(fp);
fclose(fp_temp);
if (matched == 0) {
printf("Please supply an ip address that is currently listed on the whitelist\n");
} else {
rename("../app/temp.txt", "../app/whitelist.txt");
}
}
*I didn't include my strip function but it removes \n
This may not fix your problem but you can simplify add_to_white_list to:
void add_to_white_list(char* ip) {
FILE *fp = fopen("../app/whitelist.txt", "a");
if ( fp != NULL )
{
fprintf(fp, "%s\n", ip);
fclose(fp);
}
}

How to get back pointer of pointers from a function

I have a function which open a file, read its content line by line and then push it to an array. I have managed to get the array functionnal inside the right function, but when I want to get it back to my main function, I cannot get any items of my array.
Some code will help you to understand:
My main function:
/* ----------------- MAIN ------------ */
int main(int argc, char *argv[]) {
/*... some useless code for now ... */
char **ptrLines = NULL;
ptrLines = readEventFile(ptrParam, ptrLines);
outputExecTrace(WAR, "PTRLINES x : %x", ptrLines);
outputExecTrace(WAR, "PTRLINES char[] : %s", *(ptrLines + 2));
return EXIT_SUCCESS;
}
My fileReader function:
char** readEventFile(Parameters *parameters, char **arrLine) {
FILE *fp = fopen(parameters->inputFilePath, "r");
if (fp == NULL)
exit(0);
char line[128];
int nbCharOfLine = 0;
while(1) {
fgets(line, sizeof(line), fp);
if (feof(fp))
break;
nbCharOfLine++;
}
fclose(fp);
arrLine = malloc(sizeof(line) * nbCharOfLine);
nbCharOfLine = 0;
fp = fopen(parameters->inputFilePath, "r");
while(1) {
fgets(line, sizeof(line), fp);
if (line[0] != '#') {
arrLine[nbCharOfLine] = malloc((strlen(line)+1) * sizeof(char));
strcpy(arrLine[nbCharOfLine], line);
nbCharOfLine++;
}
if (feof(fp))
break;
}
fclose(fp);
outputExecTrace(WAR, "ARRLINE x : %x", arrLine);
outputExecTrace(WAR, "ARRLINE char[] : %s", *(arrLine + 2));
return arrLine;
}
Has it is, my outputs are the followings:
WARNING: ARRLINE int : -2020552688
WARNING: ARRLINE char[] : 1 3 4 //This is the result I am looking for.
WARNING: PTRLINES int : -2020552688 // Same as ARRLINE
Segmentation fault (core dumped) // And this is because ptrLines[2] doesn't contains anything... but why ?!
How can I fix this ?
It's hard to tell exactly what happen, because you have several small problems within code, which could lead to this, try to change your code in following way:
char** readEventFile(char* fileName) {
char line[128];
int nbCharOfLine = 0;
FILE *fp = fopen(fileName, "r");
if (fp == NULL)
exit(1);
while (!feof(fp)) {
char *r = fgets(line, sizeof(line), fp); // NOTE: proper handling of fgets return value
if ((r != NULL) && (line[0] != '#'))
nbCharOfLine++;
}
fclose(fp);
char **arrLine = calloc(nbCharOfLine, sizeof(char*)); // use calloc to be sure
nbCharOfLine = 0;
fp = fopen(fileName, "r");
while (!feof(fp)) {
char *r = fgets(line, sizeof(line), fp);
if ((r != NULL) && (line[0] != '#')) {
arrLine[nbCharOfLine] = calloc(strlen(line) + 1, sizeof(char));
strcpy(arrLine[nbCharOfLine++], line);
}
}
fclose(fp);
return arrLine;
}
in your main, you will call this function like:
char **ptrLines = readEventFile(ptrParam->inputFilePath);
Not so sure this is the whole problem, but the posted code:
while(1) {
fgets(line, sizeof(line), fp);
if (line[0] != '#') {
arrLine[nbCharOfLine] = malloc((strlen(line)+1) * sizeof(char));
strcpy(arrLine[nbCharOfLine], line);
nbCharOfLine++;
}
if (feof(fp))
break;
}
is not the right approach for several reasons,
including that function feof()
is only asserted 'true' when the code has tried to read past the
end of the file.
suggest:
while( fgets(line, sizeof(line), fp) )
{
if (line[0] != '#')
{
if( NULL == (arrLine[nbCharOfLine] = malloc((strlen(line)+1) * sizeof(char)) ) )
{ // then, malloc failed
perror( "malloc failed" );
// close file and free all malloc'd areas
exit( EXIT_FAILURE );
}
// implied else, malloc successful
strcpy(arrLine[nbCharOfLine], line);
nbCharOfLine++;
}
}

Segmentation fault 11 in C on mac

I am unable to read the data from the file created. This is a very simple code and I simply cannot understand why it is not working. I have just shifted to mac and installed the developer command line tools.
My code is :
int main()
{
FILE *fp;
int lines = 0;
char *data;
data = (char *)malloc(1000);
data = NULL;
fp = fopen("1.txt", "r");
while (fgets(data, 1000, fp) != NULL)
{
printf("%s\n", data);
lines++;
}
printf("Lines = %d\n", lines);
free(data);
fclose(fp);
return 0;
}
You allocate space for data and then promptly leak it.
char *data;
data = (char *)malloc(1000);
data = NULL;
You then use fgets() with a NULL pointer, which causes undefined behavior.
fgets(data, 1000, fp)
Perhaps you should remove this line of code?
data = NULL;

Resources