2017-03-24 39 views
-1

我知道這是一個非常微不足道的問題,但我只需要快速幫助。我一直試圖弄清楚這一點現在。所有我想要做的是閱讀從具有形式如何從字符串,空格,新行和整數中的文件中只讀取整數C

8 blah blah 
10 blah blah 
2 blah blah 
3 blah blah 

我最終想只取數字,它們存儲在數組中,並把這些數字在BST的文本文件的整數。我的BST工作正常,當我有一個文件只有數字,但沒有指定的文件格式。

不要緊什麼blah是我只想得到的數字,並將它們存儲在一個數組中。如果我拿出blah's,我可以做到這一點。使用fscanf,我得到我的代碼來存儲第一個數字,它是8,但它停在那裏。在這個例子中也有四行,但是文件中有多少行並不重要。它可能是12或6.我該如何正確地做到這一點。以下是我很難解決這個問題的嘗試。

fscanf(instructionFile, "%d", &num); 

我也試着做這樣

while(!feof(instructionFile)){ 
    fscanf("%d %s %s", &num, string1, string2); 
} 

東西要儲存的一切,只使用整數,但是當我做這樣的事情,我的BST不起作用。

+0

停止。使用'fgets',然後用'strtol'解析 –

+0

另外,請參閱http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong –

+0

數字總是在開頭一條線?是否總是有一個數字?一行上能有多少數字?數字可以被字母或標點符號包圍嗎?你需要擔心跡象嗎? –

回答

1

使用fgets()來獲取一行輸入,而sscanf()來獲得整數。在您使用fscanf()的示例中,第一次調用將讀取一個int,並且由於輸入流中的下一項不是int,所以下一次調用將失敗。每次失敗後,輸入流中都會留下錯誤的輸入。通過一次獲取一行,您可以在獲取另一行輸入之前在閒暇時掃描該行。

下面是一個如何做到這一點的例子。並且請注意,您不應使用feof()來控制讀取循環;而是使用fgets()的返回值。這段代碼假設一行上的第一個條目是你想要的數據,也許帶有前導空格。格式字符串可以修改爲稍微複雜的情況。如果您需要更好地控制線條分析,則還可以使用strtok()

#include <stdio.h> 
#include <stdlib.h> 

#define MAX_LINES 100 

int main(void) 
{ 
    FILE *fp = fopen("data.txt", "r"); 
    if (fp == NULL) { 
     fprintf(stderr, "Unable to open file\n"); 
     exit(EXIT_FAILURE); 
    } 

    char buffer[1000]; 
    int arr[MAX_LINES]; 
    size_t line = 0; 

    while ((fgets(buffer, sizeof buffer, fp) != NULL)) { 
     if (sscanf(buffer, "%d", &arr[line]) != 1) { 
      fprintf(stderr, "Line formatting error\n"); 
      exit(EXIT_FAILURE); 
     } 
     ++line; 
    } 

    for (size_t i = 0; i < line; i++) { 
     printf("%5d\n", arr[i]); 
    } 

    fclose(fp); 

    return 0; 
} 

在呼叫sscanf()之前添加一個空行檢查是很好的;現在空行被認爲是格式不正確的數據。

輸出爲您的示例文件:

8 
    10 
    2 
    3 
1

如果你想從一個文件亂七八糟挑出唯一整數,那麼你實際上需要通過每次用指針來識別每個開始識讀線工作(或開始-負號碼的符號)轉換每次發現一個整數。你可以用指針和sscanf來做到這一點,或者你可以用strtol做到這一點,使用endptr參數在成功轉換後移動到下一個字符。您也可以使用面向字符的輸入(例如getcharfgetc)手動執行數字識別和轉換(如果您喜歡)。

鑑於您開始使用fgetssscanf方法,下面繼續。無論您使用的是sscanf還是strtol,整個密鑰都是在每個找到的整數之後,將下一次讀取的開始時間推進到字符,例如,

#include <stdio.h> 
#include <stdlib.h> 

#define MAXC 256 

int main (int argc, char **argv) { 

    char buf[MAXC] = ""; /* buffer to hold MAXC chars at a time */ 
    int nval = 0;   /* total number of integers found */ 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* validate file open for reading */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    while (fgets (buf, MAXC, fp)) { 

     char *p = buf;  /* pointer to line */ 
     int val,   /* int val parsed */ 
      nchars = 0;  /* number of chars read */ 

     /* while chars remain in buf and a valid conversion to int takes place 
     * output the integer found and update p to point to the start of the 
     * next digit. 
     */ 
     while (*p) { 
      if (sscanf (p, "%d%n", &val, &nchars) == 1) { 
       printf (" %d", val); 
       if (++nval % 10 == 0)  /* output 10 int per line */ 
        putchar ('\n'); 
      } 
      p += nchars;  /* move p nchars forward in buf */ 

      /* find next number in buf */ 
      for (; *p; p++) { 
       if (*p >= '0' && *p <= '9') /* positive value */ 
        break; 
       if (*p == '-' && *(p+1) >= '0' && *(p+1) <= '9') /* negative */ 
        break; 
      } 
     } 
    } 
    printf ("\n %d integers found.\n", nval); 

    if (fp != stdin) fclose (fp);  /* close file if not stdin */ 

    return 0; 
} 

示例輸入

以下兩個輸入文件演示僅挑選出的整數混合輸入的。您的文件:

$ cat dat/blah.txt 
8 blah blah 
10 blah blah 
2 blah blah 
3 blah blah 

一個非常混亂的文件

$ cat ../dat/10intmess.txt 
8572,;a -2213,;--a 6434,; 
a- 16330,;a 

- The Quick 
Brown%3034 Fox 
12346Jumps Over 
A 
4855,;*;Lazy 16985/,;a 
Dog. 
11250 
1495 

示例使用/輸出

你的情況:

$ ./bin/fgets_sscanf_int_any_ex < dat/blah.txt 
8 10 2 3 
4 integers found. 

隨着真的很亂文件:

$ ./bin/fgets_sscanf_int_any_ex <dat/10intmess.txt 
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495 

10 integers found. 

看看,讓我知道你是否有任何問題。

1

一個簡單辦法「只讀整數」就是用fscanf(file_pointer, "%d", ...)fgetc()時失敗

int x; 
int count; 
while ((count = fscanf(file_pointer, "%d", &x)) != EOF) { 
    if (count == 1) { 
    // Use the `int` in some fashion (store them in an array) 
    printf("Success, an int was read %d\n", x); 
    } else { 
    fgetc(file_pointer); // Quietly consume 1 non-numeric character 
    } 
} 

我得到了我的代碼來存儲第一個數字是8,但它停在那裏。

這是因爲違規的非數字輸入保留在FILE流中。該文本需要在某些其他方式中使用。調用fscanf(instructionFile, "%d", &num);再次簡單的結果會導致同樣的問題:fscanf()由於初始輸入爲非數字而失敗。


注:OP的代碼使用的fscanf缺少文件指針

// fscanf(????, "%d %s %s", &num, string1, string2);  
相關問題