所以我试图从这样的文件中加载信息:
TREE 1 2
BURN 5 6
...
我代码上的所有内容都运行良好,但是在读取文件的过程中,它读取了第一行并停留在那里。这是我在做什么:
int lines=0, columns=0, MAX=5;
FILE *file=NULL;
char *string;
...
string=(char *)malloc(sizeof(char)*MAX);
while ((fscanf(file, "%s %d %d", string, &lines, &colums))!=EOF) {
matrix[lines][colums]=string;
string=NULL;
}
这是代码中唯一无法正常工作的部分,其他所有工作都很好。文件打开,矩阵正确分配。它只是在1行被阻塞。 “ ...”只是分配40x40矩阵的一部分。
先感谢您!
最佳答案
将文件中的信息加载到矩阵中并不难,但是您的代码有很多方面令人困惑。首先,您似乎正在创建一个40 x 40
矩阵,然后读取一个4个字符的字符串以及其在row
矩阵中的预期column
和40 x 40
位置,尽管创建部分字符串没有错填充矩阵,您所采用的方法存在多个问题点。
如前所述,检查fscanf(...) != EOF)
不正确。 Xscaf
函数系列返回的匹配计数等于根据您的格式字符串进行的成功转换次数。例如,使用格式为"%s %d %d"
的字符串,成功读取并将行转换为return
,fscanf
和string
的匹配计数(因此为lines
的columns
)将是3
。 return
的正确用法是检查3
有效转换。例如。:
fscanf (file, "%s %zu %zu", string, &lines, &columns) == 3)
(正如其他人指出的那样,最好使用像
fgets
这样的面向行的输入功能来读取文件的行,以防止在columns
之后出现文件中的乱字符或其他格式问题,从而导致读取或转换但是,如果保证在整个输入文件中使用一致的格式,则在这种情况下可以非最佳地使用fscanf
)在阅读和分配给
matix
的过程中,还应该检查两个其他问题。首先,您应该跟踪行索引,以确保您现在确实在matrix
的末尾进行写入(例如,尝试写入41行,等等。)。例如,使用idx
跟踪索引以读取/添加的行数,并且ROWS
是常量40
,您可以执行以下操作:while (idx < ROWS && /* read each line, validate conversion */
fscanf (file, "%s %zu %zu", string, &lines, &columns) == 3) {
...
idx++;
}
其次,您需要对照
lines
和40
检查columns
的值以及字符串的长度(包括nul终止符),以确保其长度不超过matix
的末尾(例如放置超过row or column 39
的字符。假设您的字符串的最大长度为5
(4个字符+ 1),并且常量COLS
定义为40
,则可以在阅读开始时执行以下操作环: if (lines >= ROWS) { /* validate row position for string */
fprintf (stderr, "warning: invalid row index, line '%zu'\n",
idx);
continue;
}
if (columns + MAX + 1 >= COLS) { /* validate position for string */
fprintf (stderr, "warning: invalid columns + MAX, line '%zu'\n",
idx);
continue;
}
如果打算将
matrix
打印为字符串以确认代码,则还必须处理0
列与位于string
列的columns
开头之间的字符。如果需要,可以使用快速memset
进行处理。例如。: memset (matrix[lines], ' ', columns);
(您还需要确认从文件读取的
lines
和columns
是从零开始还是从一开始)最后,无需动态声明
string
。您知道string
不能超过40
,并且出于示例输入的目的,它也不能超过5
,因此,简单的静态声明大小为5
的字符数组就足够了。将所有部分放在一起,并仅为示例的打印目的添加
maxrow
限制,您可以执行以下操作:#include <stdio.h>
#include <string.h>
#define ROWS 40
#define COLS 40
#define MAX 5
int main (int argc, char **argv) {
char matrix[ROWS][COLS] = {{0}};
char string[MAX] = {0};
FILE *file = argc > 1 ? fopen (argv[1], "r") : stdin;
size_t lines, columns, idx, maxrow, i;
lines = columns = idx = maxrow = i = 0;
if (!file) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}
while (idx < ROWS && /* read each line, validate conversion */
fscanf (file, "%s %zu %zu", string, &lines, &columns) == 3) {
if (lines >= ROWS) { /* validate row position for string */
fprintf (stderr, "warning: invalid row index, line '%zu'\n",
idx);
continue;
}
if (columns + MAX + 1 >= COLS) { /* validate position for string */
fprintf (stderr, "warning: invalid columns + MAX, line '%zu'\n",
idx);
continue;
}
memset (matrix[lines], ' ', columns); /* set leading spaces */
strcpy (&matrix[lines][columns], string); /* copy string to matrix */
maxrow = lines > maxrow ? lines : maxrow; /* track max row filled */
idx++;
}
if (file != stdin) fclose (file);
for (i = 0; i < maxrow + 1; i++) /* simple test print of matrix */
printf (" %s\n", matrix[i]);
return 0;
}
(注意:如果您的编译器无法处理输入/转换为
size_t
(例如%zu
),则可以将声明更改为int
。选择size_t
的目的是lines
和columns
不能否定的。选择适当的类型可使编译器提供其他警告)编译
始终在启用警告的情况下进行编译。例:
gcc -Wall -Wextra -o bin/matrix_strings matrix_strings.c
(如果不使用
gcc
,则编译器将具有类似的选项)示例/输出
使用示例输入文件将导致以下结果:
$ ./bin/matrix_strings ../dat/tb.txt
TREE
BURN
如果您还有其他问题,请告诉我。
关于c - 读取矩阵的字符串和整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34645933/