如何只读取C

时间:2017-03-24 00:47:23

标签: c integer binary-search-tree scanf

我知道这是一个非常微不足道的问题但我需要快速帮助。我一直试图解决这个问题。我想要做的只是从具有

形式的文本文件中读取整数
 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不起作用。

3 个答案:

答案 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 :(得分: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.

仔细看看,如果您有任何问题,请告诉我。

答案 2 :(得分:1)

简单方式&#34;只读整数&#34;如果失败则使用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);