fscanf() not writing value scaned from file
I wrote some functions.
typedef struct {
unsigned long long studentID;
DATE date;
char address[256];
unsigned short isInfected;
}NAT;
int ReadAllNAT(NAT** AllNATPtr) {
FILE* NATSet = NULL;
NATSet = fopen("NATData", "r");
int dataNum = 0;
NAT* AllNAT = NULL;
if (NATSet != NULL) {
fscanf(NATSet, "%d\tDataNum", &dataNum);
AllNAT = (NAT*)malloc(dataNum * sizeof(NAT));
for (int i = 0; i < dataNum; i++) {
fscanf(NATSet, "%lld", &AllNAT[i].studentID);
fscanf(NATSet, "%d-%d-%d", &AllNAT[i].date.year, &AllNAT[i].date.month, &AllNAT[i].date.day);
fscanf(NATSet, "%d", &AllNAT[i].isInfected);
fscanf(NATSet, "%s", AllNAT[i].address);
fscanf(NATSet, "END");
}
fclose(NATSet);
*AllNATPtr = AllNAT;
}
return dataNum;
}
int WriteNAT(const NAT* newNAT, const NAT* AllNAT, int dataNum) {
FILE* NATSet = NULL;
NATSet = fopen("NATData", "w");
int isSucceed = 0;
if (NATSet != NULL) {
fprintf(NATSet, "%d\tDataNum\n", (dataNum + 1));
for (int i = 0; i < dataNum; i++) {
fprintf(NATSet, "ID\t%lld\tDate-y\t%d\tDate-m\t%d\tDate-d\t%d\tAddress\t%s\tI\t%d\tEND\n", AllNAT[i].studentID, AllNAT[i].date.year, AllNAT[i].date.month, AllNAT[i].date.day, AllNAT[i].address, AllNAT[i].isInfected);
}
fprintf(NATSet, "ID\t%lld\tDate-y\t%d\tDate-m\t%d\tDate-d\t%d\tAddress\t%s\tI\t%d\tEND\n", newNAT->studentID, newNAT->date.year, newNAT->date.month, newNAT->date.day, newNAT->address, newNAT->isInfected);
fclose(NATSet);
isSucceed = 1;
}
return isSucceed;
}
I use them to change a file. Those functions can add new line to this file.
2 DataNum
ID 11 Date-y 1 Date-m 1 Date-d 1 Address 1 I 0 END
ID 12 Date-y 1 Date-m 1 Date-d 1 Address 1 I 0 END
The number "2" stands for the number of lines.
But something went wrong. I use debug mode to find the value of the struct. I saw fscan() didn't write the value which scaned from file and return 0. I changed MSVC to MinGW-gcc, but it still doesn't work. How to make fscanf() works properly? Do I need to redesign a new formant of it? Please lend me a hand. I will be very grateful.
How to make "fscanf()" works properly?
(OP used the wrong format, wrong specifiers, %s lacked width & swapped 2 structure members)
Do not use fscanf()
to read as it makes error detection and recovery difficult.
Instead use fgets()
for all file input to read a line into a string ...
char buf[sizeof(NAT) * 2]; // be generous
if (fgets(buf, sizeof buf, NATSet)) {
... and now parse. To parse the string, one nice way uses sscanf()
with " %n"
to detect the complete parsing of one line.
// ID 11 Date-y 1 Date-m 1 Date-d 1 Address 1 I 0 END
int n = 0;
sscanf(buf, "ID %llu Date-y %d Date-m %d Date-d %d Address %255s I %hu END %n",
&AllNAT[i].studentID, &AllNAT[i].date.year, &AllNAT[i].date.month,
&AllNAT[i].date.day, AllNAT[i].address, &AllNAT[i].isInfected, &n);
if (n == 0 || buf[n]) {
printf("Invalid input <%s>\n", buf);
}
Note: "%255s"
will not well parse an address with spaces in it. To handle that, post sample input.