我正在嘗試使用 fscanf 獲取一個文本檔案并以相同的格式簡單地列印它(最終它將用于填充結構陣列)。
當我使用 fscanf 時,它會列印一些不屬于文本的值,我不確定它們來自哪里。我已將一小部分輸入文本檔案和輸出放在代碼部分下方。
我想在頁面上水平列印的值都在輸出的第一列,這讓我覺得這與我定義 fprint 陳述句的方式有關?第一列中的每個正確值后面都是我不知道從何而來的值。
任何幫助將不勝感激。
#include <stdlib.h>
int count_lines(char file[]) {
FILE* f = fopen(file, "r"); /* declaration of file pointer */
char x;
int c = 0; /* declaration of variable */
f = fopen(file, "r");
if (f == NULL) {
printf("Cannot open file for reading");
return -1;
}
while ((x = fgetc(f)) != EOF) {
if (x == '\n') {
c = c 1;
}
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
return -1;
}
printf("Number of lines = %d\n", c);
return c;
}
struct votes {
char state[100]; /* state name */
long dempv; /* democrats popular votes */
long demev; /* democrats electoral votes */
long reppv; /* republicans popular votes */
long repev; /* republicans electoral votes */
};
void initialise_votes(char file[], struct votes* arr, int nlines) {
FILE* f = fopen(file, "r");
char temp1[20];
long temp2;
long temp3;
long temp4;
long temp5;
if (f == NULL) {
printf("Cannot open file for reading\n");
}
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
printf("%s\t%ld\t%ld\t%ld\t%ld\n", temp1, temp2, temp3, temp4, temp5);
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
}
}
int main(void) {
char s_in[] = "uselection2012.txt"; /* input data file */
int nlines;
struct votes* arr;
nlines = count_lines(s_in);
arr = (struct votes*)malloc(sizeof(struct votes) * nlines);
initialise_votes(s_in, arr, nlines);
return 0;
}
輸入檔案:
Alabama 795696 0 1255925 9
Alaska 122640 0 164676 3
Arizona 1025232 0 1233654 11
Arkansas 394409 0 647744 6
California 7854285 55 4839958 0
輸出:
Alabama 6356696 -37862896 6380 0
795696 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1255925 6356696 -37862896 6380 0
9 6356696 -37862896 6380 0
Alaska 6356696 -37862896 6380 0
122640 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
164676 6356696 -37862896 6380 0
3 6356696 -37862896 6380 0
Arizona 6356696 -37862896 6380 0
1025232 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1233654 6356696 -37862896 6380 0
11 6356696 -37862896 6380 0
Arkansas 6356696 -37862896 6380 0
394409 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
647744 6356696 -37862896 6380 0
6 6356696 -37862896 6380 0
California 6356696 -37862896 6380 0
7854285 6356696 -37862896 6380 0
55 6356696 -37862896 6380 0
4839958 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
uj5u.com熱心網友回復:
您的 scanf 格式字串包含逗號,但您的輸入資料不包含逗號。
請注意,fscanf回傳 EOF 或成功掃描的值的數量。您可以并且應該使用該回傳值來檢查錯誤,這樣做會指出您代碼中的問題。
uj5u.com熱心網友回復:
fscanf 格式字串中的逗號告訴fscanf在檔案中期待逗號,如果找不到它們就停止。
您的檔案中沒有逗號,因此fscanf在讀取轉換的“字串”后停止%s。
從格式字串中洗掉逗號。
測驗 的回傳值是否fscanf等于您期望分配的專案數,而不僅僅是它不等于EOF。
uj5u.com熱心網友回復:
可避免的編碼弱點導致 OP 的困難
如果代碼根據 5 的期望結果而不是許多不正確的結果之一檢查回傳值EOF, 0, 1, 2, 3, 4,那么問題將很快縮小為 scanf 失敗。
// while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
其他事宜
空白
除了樣式之外,沒有任何價值,因為已經消耗了" "可選"%ld"的"%ld"前導空白。
然而,在 . 之前放置一個空格","以允許在','.
while (fscanf(f, "%s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
緩沖區溢位
永遠不要"%s"在(f)scanf()函式中使用。使用寬度限制,否則有緩沖區溢位的風險。
// width --------vv
while (fscanf(f, "s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
fgetc() 回傳一個 int
fgetc(f)回傳 257 個不同的值。使用 anint來正確區分。
// char x;
int x;
...
while ((x = fgetc(f)) != EOF) {
行數可能會失敗
行數只計算'\n'. 如果檔案只包含"abc 1 2 3 4",沒有'\n',則行數將報告為 0。
而是計算行首的數量。
count = 0;
int prior = '\n';
while ((x = fgetc(f)) != EOF) {
if (prior == '\n') {
count ;
}
prior = x;
...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410334.html
標籤:
