从 C 文件中读取多个整数行

Read multiple integer lines from a file in C

4
1 2 4 3 5 4 5
4 1 7 3 3
2 1 3 4 10

第一行是顶点数。

从第二行第一列开始,是顶点。下一组'pairs'分别是顶点和权重。

我尝试使用 fscanf(fptr, "%[^\n]", vertices); 只读取第一行,这给出了垃圾值。 vertices = fgetc(fptr); 给了我不同的价值但不是垃圾(我认为)

从第二行开始,我不确定如何添加到我的 adj 列表有向图中,但我需要帮助才能获得这些值。

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

int main()
{
    FILE *fptr;
    fptr = fopen("adjacencylist.txt", "r");
    if (fptr == NULL) exit(1);

    int vertices, c;
    //fscanf(fptr, "%[^\n]", vertices);
    //vertices = fgetc(fptr);
    vertices = fgetc(fptr);
    printf("%d", vertices);
    fclose(fptr);
}

您正在处理的数据是按行处理的(除了读取的第一个值,技术上它只是一个计数器,但仍然驻留在它自己的行上)。这意味着您需要一种一次处理数据行的策略。在提取顶点+权重对时,您还需要帮助移动“光标”(实际上只是一个偏移量)。

一种方法是使用 getline(POSIX 的一部分)动态读取行,然后使用 sscanf 提取值,特别是使用 %n 添加格式说明符以跟踪在最后一次格式化读取中消耗了多少字符。此功能将允许您提前行缓冲区中的下一个读取位置,以便跟踪从何处获取下一对顶点+权重。

如果您无法访问 POSIX getline,您总是可以 (a) 编写自己的,或者 (b) 只使用足够大的行缓冲区来确保完整捕获您的最长的线。但不会撒谎;有了 getline 就容易多了。

总之..

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (argc < 2)
        return EXIT_FAILURE;

    // open the file
    FILE * fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        perror(argv[1]);
        return EXIT_FAILURE;
    }

    // read the first counter of vertices
    int n = 0;
    if (fscanf(fp, "%d", &n) == 1 && n > 0)
    {
        // TODO setup your vesticies here using 'n'
        printf("%d verticies will be used\n", n);

        // skip to end of line
        int c;
        while ((c = fgetc(fp)) != EOF && c != '\n');

        // read one line at a time
        char *line = NULL;      // dynamic line pointer
        size_t len = 0;         // length of last line-read

        while (getline(&line, &len, fp) > 0)
        {
            char *cur = line;   // current line position
            int ccs = 0;        // no. of chars read on last scan
            int v1;             // beginning vertex of each line

            // extract the vertex number
            if (sscanf(cur, "%d%n", &v1, &ccs) == 1)
            {
                printf("v1(%d) : ", v1);

                // advance line position past data-just-read
                cur += ccs;

                // read second vertex and weight as pairs
                int v2;
                int w;
                while (sscanf(cur, "%d %d%n", &v2, &w, &ccs) == 2)
                {
                    // TODO: setup the [v1,v2] = w relationship here
                    printf("(%d,%d) ", v2, w);

                    // advance cursor past data just-read
                    cur += ccs;
                }

                fputc('\n', stdout);
            }
        }

        // release whatever buffer we managed
        free(line);
    }

    // close the file before continuing the program
    fclose(fp);

    // TODO: use your data here

    return 0;
}

运行 针对你的输入数据,输出是:

4 vertices will be used
v1(1) : (2,4) (3,5) (4,5) 
v1(4) : (1,7) (3,3) 
v1(2) : (1,3) (4,10) 

请参阅此处了解 scanf 函数族的具体信息,并特别注意上面代码中 %n 的使用。它能够获取刚刚处理的字符数,以及如何将 cur 前进到行缓冲区的下一个读取位置,这对上述工作方式至关重要。