[英]2nd fgets returns segmentation fault after reading 192/200 lines of text from file
我正在尝试从文本文件中读取 200 行文本,并将每行的值存储到一个结构中。 这只是不工作部分的一小部分。 在整个代码中,我询问用户是否希望读取不同的文本文件。 它第一次完美运行,但是当用户说是读取不同的文件时,它只读取并存储文本文件的 200 行中的前 192 行,然后返回一个段错误。
我尝试在整个代码的各个部分打印出随机字母,以确定哪一行返回了段错误,并且(根据我发现的内容),这是进入内部的 while 条件,我无法弄清楚为什么它会给出段错误。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[]) {
FILE *f1;
int i = 0;
struct pNames popNames;
char fileName[20];
char maleSNumber[20];
char femaleSNumber[20];
char string[200];
fileName[0] = '\0';
sprintf(fileName, "%d", popNames.year);
strcat(fileName, "Names.txt");
if ((f1 = fopen(fileName, "r")) != NULL) {
while (fgets(string, 200, f1) != NULL) {
sscanf(string, "%d %s %s %s %s",
&popNames.rank[i],
popNames.maleName[i], maleSNumber,
popNames.femaleName[i], femaleSNumber);
printf("%d %s %s %s %s\n",
popNames.rank[i],
popNames.maleName[i], maleSNumber,
popNames.femaleName[i], femaleSNumber);
removeCommas(maleSNumber);
removeCommas(femaleSNumber);
popNames.maleNumber[i] = atoi(maleSNumber);
popNames.femaleNumber[i] = atoi(femaleSNumber);
i++;
}
} else {
printf("Cannot open %s\n", fileName);
return (-1);
}
}
结构定义:
#define MAXLENGTH 20
#define ROWS 200
/* Struct definitions */
struct pNames {
int year;
int rank[ROWS];
char maleName[ROWS][MAXLENGTH];
int maleNumber[ROWS];
char femaleName[ROWS][MAXLENGTH];
int femaleNumber[ROWS];
};
removeCommas()
的定义:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int removeCommas(char *num) {
int i;
int newNum = 0;
char *pointer;
pointer = strchr(num, ',');
while (pointer != NULL) {
i = (int)(pointer - num);
strcpy(&num[i], &num[i + 1]);
newNum += 1;
pointer = strchr(num, ',');
}
return (newNum);
}
它应该读取、存储每行的部分内容并打印出文本文件的所有 200 行,但它仅适用于前 192 行(第二次使用它时,当用户要求更改文本文件时)。 1个文本行的格式应该是:
[rank][maleName][numMaleNameOccurences][femaleName][numFemaleNameOccurences]
(例如1 John 89,950 Mary 91,668
)
我了解您只发布了代码片段,但这里有一些明显的问题:
snprintf
而不是sprintf
和strcat
popNames.year
未初始化fgets
sscanf()
的返回值sscanf()
中%s
字段的最大字符数。i
个条目之前测试i
的值,如果文件异常大,您将获得未定义的行为您的removeCommas()
具有未定义的行为,因为您使用重叠字符串调用strcpy
。 这不太可能是您的段错误的原因,但这里有一个简化和更正的版本:
int removeCommas(char *num) {
int newNum = 0;
char *p = num;
while ((*num = *p++) != '\0') {
if (*num != ',')
num++;
else
newNum++;
}
return newNum;
}
这是main()
function 的修改版本:
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *f1;
int i;
struct pNames popNames;
char fileName[20];
char maleSNumber[20];
char femaleSNumber[20];
char string[200];
snprintf(fileName, sizeof fileName, "%dNames.txt", popNames.year);
if ((f1 = fopen(fileName, "r")) == NULL) {
printf("Cannot open %s\n", fileName);
return -1;
}
i = 0;
while (i < 200 && fgets(string, sizeof string, f1) != NULL) {
if (sscanf(string, "%d %19s %19s %19s %19s",
&popNames.rank[i],
popNames.maleName[i], maleSNumber,
popNames.femaleName[i], femaleSNumber) != 5) {
printf("invalid input: %s", string);
continue;
}
printf("%d %s %s %s %s\n",
popNames.rank[i],
popNames.maleName[i], maleSNumber,
popNames.femaleName[i], femaleSNumber);
removeCommas(maleSNumber);
removeCommas(femaleSNumber);
popNames.maleNumber[i] = atoi(maleSNumber);
popNames.femaleNumber[i] = atoi(femaleSNumber);
i++;
}
fclose(f1);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.