简体   繁体   English

从 C 的文件中读取多个 integer 行

[英]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

The first line is number of vertices.第一行是顶点数。

From second line, first column, is the vertex.从第二行,第一列,是顶点。 Next set of 'pairs' are vertex and weight respectively.下一组“对”分别是顶点和权重。

I tried just to read only first line using fscanf(fptr, "%[^\n]", vertices);我尝试使用fscanf(fptr, "%[^\n]", vertices);只读取第一行which gave garbage value.这给了垃圾价值。 vertices = fgetc(fptr); gave me a different value but not garbage (I think)给了我不同的价值,但不是垃圾(我认为)

The second line onwards, I'm not sure how to add to my adj list directed graph, but I need help just to get those values.从第二行开始,我不确定如何添加到我的 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);
}

The data you're processing is per-line (save for the first value read, which technically is just a counter, but still resides on its own line).您正在处理的数据是每行的(保存第一个值读取,技术上只是一个计数器,但仍驻留在自己的行上)。 That means you need a strategy for processing data line at a time.这意味着您需要一次处理数据线的策略。 You also need to facilitate moving a "cursor" (really just an offset) through the line as you extract vertex+weight pairs.当您提取顶点+权重对时,您还需要促进通过线移动“光标”(实际上只是一个偏移量)。

One way to do this is using getline (part of POSIX) for reading the lines dynamically, then using sscanf to extract the values, and in particular using the %n added format specifier to track how many characters were consumed in the last formatted read.一种方法是使用getline (POSIX 的一部分)动态读取行,然后使用sscanf提取值,特别是使用%n添加的格式说明符来跟踪上次格式化读取中消耗了多少字符。 This feature will allow you to advance a next-read-from position in the line buffer so as to track where to get the next pair of vertex+weight.此功能将允许您在行缓冲区中推进 position 的下一次读取,以便跟踪从何处获取下一对顶点+权重。

If you don't have access to POSIX getline you could always (a) write your own, or (b) just use a sufficiently sized line buffer to ensure complete capture of your longest line.如果您无法访问 POSIX getline ,您始终可以 (a) 自己编写,或者 (b) 只使用足够大的行缓冲区来确保完全捕获最长的行。 But not going to lie;但不会说谎; having getline makes it a ton easier.拥有getline使它更容易。

Anyway..反正..

#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;
}

Run against your input data, the output is:针对您的输入数据运行,output 是:

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) 

See here for the specific of the scanf family of functions, and note particularly the use of %n in the code above.有关scanf系列函数的具体信息,请参见此处,并特别注意上面代码中%n的使用。 Its ability to reap how many characters were just processed, and thus how to advance cur to the next read position of the line buffer, is critical to how the above works.它获取刚刚处理了多少个字符的能力,因此如何将cur推进到下一次读取行缓冲区的 position,对于上述工作方式至关重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM