I've cut out the code that works so the code below is not a whole program but the problematic part.
I get a segmentation fault on the fscanf line below. I added the character width for each variable to try and fix it so I don't understand why it would seg fault.
I read from a CSV file into an array of structs.
My main is just this:
#include <stdio.h>
#include <stdlib.h>
main()
{
menu();
}
Then menu.c :
#include <stdio.h>
#include <stdlib.h>
#include "DatabaseOps.h"
#include "menu.h"
#define SIZE 1000 //max size assumed to be 1000
void menu()
{
int j, lastID; //keeping track of id numbers used
Person* persons;
persons = (Person*)malloc(SIZE * sizeof(Person)); /*declaring array of person structs on the heap*/
for(j = 0; j < SIZE; j++) /*initialise all IDs to -1*/
{
persons[j].ID = -1;
}
int option = 1;
while (option!=7)
{
printf("1. Load Database\n");
scanf("%d", &option);
switch (option)
{
case 1:
printf("\nLoading Database\n\n");
lastID = loadDb(persons);
break;
default:
printf("Invalid choice, please try again\n\n");
break;
}
}
}
Persons is defined in menu.h like so:
typedef struct Person
{
int ID;
int salary;
int deleted;
char salutation[4];
char firstName[21];
char surName[31];
char job[16];
} Person;
And then the DatabaseOps.c file that causes the error:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DatabaseOps.h"
#include "menu.h"
int loadDb(Person *inPersons) //function reads csv file into an array of Employee structs
{
int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/
char* fileName = malloc( 100 * sizeof( char ));
printf("Enter name of CSV file: ");
scanf("%99s", fileName);
FILE* f = fopen(fileName, "r");
if(f==NULL) /*If the file doesn't exist, return to menu*/
{
printf("Error: could not open file\n");
}
else
{ /*the fscanf function uses grouping by commas to seperate the CSV values - [^,]*/
while(fscanf(f, "%d,%3[^,],%20[^,],%30[^,],%15[^,],%d,%d", &inPersons[i].ID, inPersons[i].salutation, inPersons[i].firstName, inPersons[i].surName, inPersons[i].job, &inPersons[i].salary, &inPersons[i].deleted)!=EOF)
{
newID = inPersons[i].ID; //Keeping track of the last used ID
i++;
}
}
fclose(f);
return newID;
}
Valgrind gives me this error, which I'm not sure how to interpret:
==19378== Use of uninitialised value of size 4
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378== by 0x80485B5: menu (menu.c:29)
==19378== by 0x804852E: main (main.c:6)
==19378==
==19378== Invalid write of size 4
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378== by 0x80485B5: menu (menu.c:29)
==19378== by 0x804852E: main (main.c:6)
==19378== Address 0x9acac288 is not stack'd, malloc'd or (recently) free'd
==19378==
==19378==
==19378== Process terminating with default action of signal 11 (SIGSEGV)
==19378== Access not within mapped region at address 0x9ACAC288
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378== by 0x80485B5: menu (menu.c:29)
==19378== by 0x804852E: main (main.c:6)
int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/
i
需要初始化为0。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.