簡體   English   中英

如何從C中帶有字符串,空格,換行符和整數的文件中僅讀取整數

[英]How to read only integers from a file with strings, spaces, new lines and integers in C

我知道這是一個非常瑣碎的問題,但我只需要快速幫助。 我已經嘗試了一段時間了。 我要做的就是從具有以下形式的文本文件中讀取整數:

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

我最終只想取數字,將它們存儲在數組中,然后將這些數字放入BST中。 當我的文件只有數字而不是指定的文件格式時,我的BST可以正常工作。

不要緊,什么blah是我只是想獲得的號碼,並將其存儲在數組中。 如果我拿出blah's我可以做到blah's 使用fscanf ,我得到了存儲第一個數字8 ,但是它在那里停止了。 同樣在此示例中,有四行,但是文件中有多少行都沒有關系。 可能是12或6。如何正確執行此操作。 以下是我為解決此問題所做的嘗試。

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

我也嘗試做類似的事情

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

要存儲所有內容,只能使用整數,但是當我執行此類操作時,我的BST無法正常工作。

使用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

如果您只想從一堆文件中挑選整數,那么實際上您需要遍歷讀取的每一行,並用一個指針來標識每個起始數字(或起始-負數的符號),一次轉換找到的每個整數。 您可以使用指針和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.

仔細看一下,如果您有任何問題,請告訴我。

一種“只讀整數”的簡單方法是在失敗時使用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的代碼缺少FILE指針

// fscanf(????, "%d %s %s", &num, string1, string2);    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM