从 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
前进到行缓冲区的下一个读取位置,这对上述工作方式至关重要。
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
前进到行缓冲区的下一个读取位置,这对上述工作方式至关重要。