[英]fscanf printing unknown values
我正在嘗試使用 fscanf 獲取一個文本文件並以相同的格式簡單地打印它(最終它將用於填充結構數組)。
當我使用 fscanf 時,它會打印一些不屬於文本的值,我不確定它們來自哪里。 我已將一小部分輸入文本文件和 output 放在代碼部分下方。
我想在頁面上水平打印的值都在 output 的第一列,這讓我覺得這與我如何定義我的 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
Output:
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
您的 scanf 格式字符串包含逗號,但您的輸入數據不包含逗號。
請注意, fscanf
返回 EOF 或成功掃描的值的數量。 您可以並且應該使用該返回值來檢查錯誤,這樣做會指出您代碼中的問題。
fscanf
格式字符串中的逗號告訴fscanf
期望文件中有逗號,如果找不到它們就停止。
您的文件中沒有逗號,因此fscanf
在讀取%s
轉換的“字符串”后停止。
從格式字符串中刪除逗號。
測試fscanf
的返回值是否等於您希望分配的項目數,而不僅僅是它不等於EOF
。
可避免的編碼弱點導致 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) {
緩沖區溢出
切勿在(f)scanf()
function 中使用"%s"
。 使用寬度限制,否則有緩沖區溢出的風險。
// width --------vv
while (fscanf(f, "%19s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
fgetc()
返回一個int
fgetc(f)
返回 257 個不同的值。 使用int
正確區分。
// 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;
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.