fscanf() 不写入从文件扫描的值
fscanf() not writing value scaned from file
我写了一些函数。
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;
}
我用它们来更改文件。这些函数可以向该文件添加新行。
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
数字“2”代表行数。
但是出了点问题。我使用调试模式来查找结构的值。我看到 fscan() 没有写入从文件和 return 0 扫描的值。我将 MSVC 更改为 MinGW-gcc,但它仍然不起作用。如何使 fscanf() 正常工作?我需要重新设计它的新共振峰吗?请帮帮我。我将不胜感激。
How to make "fscanf()" works properly?
(OP 使用了错误的格式,错误的说明符,%s 缺少宽度并交换了 2 个结构成员)
请勿使用 fscanf()
进行阅读,因为这会使错误检测和恢复变得困难。
而是使用 fgets()
作为 all 文件输入,将 line 读入 string ...
char buf[sizeof(NAT) * 2]; // be generous
if (fgets(buf, sizeof buf, NATSet)) {
...现在解析。要解析字符串,一种很好的方法是使用 sscanf()
和 " %n"
来检测一行的完整解析。
// 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);
}
注意:"%255s"
不能很好地解析其中包含空格的地址。为了处理这个问题,post 示例输入。
我写了一些函数。
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;
}
我用它们来更改文件。这些函数可以向该文件添加新行。
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
数字“2”代表行数。
但是出了点问题。我使用调试模式来查找结构的值。我看到 fscan() 没有写入从文件和 return 0 扫描的值。我将 MSVC 更改为 MinGW-gcc,但它仍然不起作用。如何使 fscanf() 正常工作?我需要重新设计它的新共振峰吗?请帮帮我。我将不胜感激。
How to make "fscanf()" works properly?
(OP 使用了错误的格式,错误的说明符,%s 缺少宽度并交换了 2 个结构成员)
请勿使用 fscanf()
进行阅读,因为这会使错误检测和恢复变得困难。
而是使用 fgets()
作为 all 文件输入,将 line 读入 string ...
char buf[sizeof(NAT) * 2]; // be generous
if (fgets(buf, sizeof buf, NATSet)) {
...现在解析。要解析字符串,一种很好的方法是使用 sscanf()
和 " %n"
来检测一行的完整解析。
// 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);
}
注意:"%255s"
不能很好地解析其中包含空格的地址。为了处理这个问题,post 示例输入。