关于C#:fscanf-尝试扫描int的txt文件,fscanf仅读取1s

fscanf— trying to scan txt file of ints, fscanf only reads 1s

我正在尝试使用fscanf读取包含25个整数的文件并将其存储在内存中。 但是,似乎对于前12个值,而不是扫描文件fscanf中的实际int总是显示为1。第13个值显示为-1,然后下面代码中的while循环终止。 知道为什么会这样吗? 谢谢你的帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <stdlib.h>
#include"matrix.h"

#define ROWS 5
#define COLS 5

void load_file(FILE* file, int** p);

int main()
{


    FILE* f1;
    f1 = fopen("twenty-five-ints.txt","r");
    int p=0;
    int* matrix = &p;
    load_file(f1, &matrix);

}

void load_file(FILE* file, int** p) {

    *p = malloc(25*sizeof(int));

    int number = 0;
    int i = 0;

    while (fscanf(file,"%d", &number) != EOF) {
        *(*p + i) = fscanf(file,"%d", &number);
        printf("%d", *(*p + i));
        i++;
    }
    printf("\
"
);
}

while循环内的printf语句打印出12个,中间用空格隔开,后跟-1。


有两件事要提及。

  • 删除一个fscanf()呼叫。否则,您将最终失去扫描的所有替代值。
  • fscanf()不返回扫描值。如果找到了一个宏,它将扫描的值存储在提供的自变量(&number)中。使用参数获取扫描值。您可以使用返回值检查对fscanf()的调用是否成功。
  • 引用手册页,(重点是我的)

    The scanf() family of functions scans input according to format as described below. This format may contain conversion specifications; the results from such conversions, if any, are stored in the locations pointed to by the pointer arguments that follow format. [...]


    您不应两次fscanf(),而应将fscanf()与要扫描的预期字段数进行比较。

    1
    2
    while ((i < 25) && (fscanf(file,"%d", (*p + i)) == 1))
        printf("%d", *(*p + i++));

    另外,fscanf()不返回扫描值,在这种情况下您希望它返回什么?

    1
    fscanf(file,"%s%d%", &string, &integer);

    额外考虑:

  • 使用索引符号解引用指针。
  • 使用附加指针以避免混淆。
  • 检查malloc()的返回值
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void
    load_file(FILE *file, int **data)
    {
        int *pointer;
        size_t i;

        *data = NULL; // So you can test this after the call to the function

        pointer = malloc(25 * sizeof(**data));
        /*                ^ if this is a constant, this doesn't make a lot of sense */
        /*                  because you can use an array instead.                   */
        if (pointer == NULL)
            return;

        for (i = 0 ; ((i < 25) && (fscanf(file,"%d", &pointer[i]) == 1) ; ++i)
            printf("%d", pointer[i]);
        printf("\
    "
    );

        *data = pointer;
    }

    我认为此功能的设计不当。您无法验证读取的值是否实际上为25,也不能在任何地方指定该值。如果您希望函数读取给定数量的最大整数,请尝试以下操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    size_t
    load_file(FILE *file, int **data, size_t maximum)
    {
        int *pointer;
        size_t i;

        *data = NULL; // So you can test this after the call to the function

        pointer = malloc(maximum * sizeof(**data));
        if (pointer == NULL)
            return;

        for (i = 0 ; ((i < maximum) && (fscanf(file,"%d", &pointer[i]) == 1) ; ++i)
            ;
        *data = pointer;
        return i;
    }

    使用此功能,您可以执行此操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int *data;
    // We assume that FILE * is a valid stream
    size_t count = load_file(file, &data, 25);
    if (data != NULL)
    {
        for (size_t i = 0 ; i < count ; ++i)
            fprintf(stdout,"%d", data[i]);
        fputc('\
    '
    , stdout);
        free(data);
    }