我正在尝试读取一个文本文件并提取"X"的坐标,以便将其放置在地图上文本文件是
10 20
9 8 X
2 3 P
4 5 G
5 6 X
7 8 X
12 13 X
14 15 X
我尝试了多次,但无法提取相关数据并将其放在单独的变量中进行绘图我对c很陌生,正在努力学习,所以非常感谢任何帮助
提前感谢
在我的前几条评论中,我提出了一个点结构数组。
以下是您为此重构的代码。
我将scanf
更改为使用%s
而不是%c
作为点名称。它概括了点名称,[可能]与输入行配合得更好,因为[I认为]%c
不会正确匹配。
它编译但未经测试:
#include <stdio.h>
#include <stdlib.h>
struct point {
int x;
int y;
char name[8];
};
struct point *points;
int count;
int map_row;
int map_col;
void
read_data(const char *file_name)
{
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
/* if the file opened is empty or has any issues, then show the error */
perror("File Error");
return;
}
/* get the dimensions from the file */
fscanf(fp, "%d %d", &map_row, &map_col);
map_row = map_row + 2;
map_col = map_col + 2;
while (1) {
// enlarge dynamic array
++count;
points = realloc(points,sizeof(*points) * count);
// point to place to store data
struct point *cur = &points[count - 1];
if (fscanf(fp, "%d %d %s", &cur->x, &cur->y, cur->name) != 3)
break;
}
// trim to amount used
--count;
points = realloc(points,sizeof(*points) * count);
fclose(fp);
}
有很多方法可以实现这一点。Craig在使用struct
来协调不同类型的数据的便利性方面有一些非常好的观点。这种方法使用fgets()
进行读取,并使用sscanf()
解析所需的数据。这一好处消除了匹配失败在输入流中留下未读字符的风险,这将从匹配失败开始破坏剩余的读取。使用fgets()
读取时,您一次消耗一行输入,并且该读取与使用sscanf()
解析值无关。
将其放在一起,并允许文件名由程序的第一个参数提供(或者如果没有提供参数,则默认从stdin
读取(,您可以执行:
#include <stdio.h>
#define MAXC 1024 /* if you need a constand, #define one (or more) */
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to hold each line */
int map_row, map_col; /* map row/col variables */
/* use filename provided as 1st argument (stdin if none provided) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open");
return 1;
}
/* read/validate first line saving into map_row, map_col */
if (!fgets (buf, MAXC, fp) ||
sscanf (buf, "%d %d", &map_row, &map_col) != 2) {
fputs ("error: EOF or invalid map row/col data.n", stderr);
return 1;
}
/* loop reading remaining lines, for used as line counter */
for (size_t i = 2; fgets (buf, MAXC, fp); i++) {
char suffix;
int x, y;
/* validate parsing x, y, suffix from buf */
if (sscanf (buf, "%d %d %c", &x, &y, &suffix) != 3) {
fprintf (stderr, "error: invalid format line %zu.n", i);
continue;
}
if (suffix == 'X') { /* check if line suffix is 'X' */
printf ("%2d %2d %cn", x, y, suffix);
}
}
if (fp != stdin) { /* close file if not stdin */
fclose (fp);
}
}
(注意:这只是说明了从后缀为'X'
的行读取和隔离值。数据处理和计算由您决定(
示例使用/输出
使用dat/coordinates.txt
中的数据,您可以执行以下操作:
$ ./bin/readcoordinates dat/coordinates.txt
9 8 X
5 6 X
7 8 X
12 13 X
14 15 X
正如Craig所指出的,如果您需要存储匹配的数据,那么struct
数组提供了一个很好的解决方案。