所以我试图从这样的文件中加载信息:
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矩阵的一部分。
提前谢谢!
答案 0 :(得分:0)
while ((fscanf(file, "%s %d %d", string, &lines, &colums))!=EOF) {
matrix[lines][colums]=string;
string=NULL;
}
您不应将字符串指针设置为NULL
。这样它就变成了NULL pointer
,并且在下一个循环中你尝试fscanf()
到一个NULL指针,并且还会泄漏分配的内存。
lines
和colum(n)s
中的读数可能高于40x40 matrix
。最好检查一下。
另外:fscanf()
的返回值可能不是EOF
:
如果发生读取错误或达到文件结尾 阅读,设置正确的指标( feof或ferror )。而且,如果有的话 在成功读取任何数据之前发生,返回EOF。
matrix[lines][colums]=string;
此处,您将pointer
存储在matrix[][]
中,而不是字符串内容。你需要在这里使用像strcpy()
这样的东西。
您还需要检查变量的名称:
columns=0
, &colums)
matrix[lines][colums]
colums vs colum n s。
答案 1 :(得分:0)
将文件中的信息加载到矩阵中并不困难,但是代码的许多方面都令人困惑。首先,您似乎正在创建40 x 40
矩阵,然后在您的{中读取 4个字符字符串及其预定的row
和column
位置{1}}矩阵,虽然创建一个部分填充的矩阵没有任何问题,但你采取的方法有几个麻烦点。
正如所指出的,检查40 x 40
是不正确的。 fscanf(...) != EOF)
系列函数返回的匹配计数等于根据 format-string 发生的成功转化次数。例如,使用格式字符串Xscaf
,匹配计数(以及"%s %d %d"
的{{1}}),以便成功读取和转换一行进入return
,fscanf
和string
将是lines
。正确使用columns
将检查3
有效转化。 e.g:
return
(正如其他人已经注意到,使用面向行的输入函数(如3
)读取文件的行可能更好,以防止fscanf (file, "%s %zu %zu", string, &lines, &columns) == 3)
之后的文件中的杂散字符1}}或其他格式问题,导致读取或转换失败。但是,如果保证整个输入文件的格式一致,则在这种情况下可以非最佳地使用fgets
在阅读和分配到columns
期间,您还应该检查另外两个问题。首先,您应该跟踪行索引,以确保您现在写入fscanf
的结尾(例如,尝试写入41行等)。例如,matix
跟踪读取/添加的行数的索引,matrix
是常量idx
,您可以执行以下操作:
ROWS
其次,您需要检查40
对while (idx < ROWS && /* read each line, validate conversion */
fscanf (file, "%s %zu %zu", string, &lines, &columns) == 3) {
...
idx++;
}
和lines
的值以及字符串的长度(包括 nul-terminator )确保它不会延伸到40
的末尾(例如,将字符放在columns
之外。假设你的字符串的最大长度为matix
(4个字符+ 1)和一个常量row or column 39
定义为5
,您可以在阅读循环开始时执行以下操作:
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
处理。 e.g:
columns
(您还需要确认从您的文件中读取的memset
和 memset (matrix[lines], ' ', columns);
是零还是一个 - p>
最后,无需动态声明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
如果您还有其他问题,请与我们联系。
答案 2 :(得分:0)
您无法仅使用=
复制字符串。请改用strcpy()
:
#include <stdio.h>
#include <string.h>
int main()
{
int lines = 0, columns = 0;
char string[5];
char matrix[40][40][5];
FILE *file = NULL;
if ((file = fopen("source.txt", "r")) == NULL)
{
perror("fopen");
return 1;
}
while ((fscanf(file, "%s %d %d", string, &lines, &columns)) != EOF)
{
strcpy(matrix[lines][columns], string);
printf("matrix[%d][%d]:%s\n", lines, columns, matrix[lines][columns]);
}
return 0;
}