[英]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.