读取matriix的字符串和int

时间:2016-01-07 01:32:15

标签: c

所以我试图从这样的文件中加载信息:

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矩阵的一部分。

提前谢谢!

3 个答案:

答案 0 :(得分:0)

while ((fscanf(file, "%s %d %d", string, &lines, &colums))!=EOF) { 
    matrix[lines][colums]=string;
    string=NULL;
}

您不应将字符串指针设置为NULL。这样它就变成了NULL pointer,并且在下一个循环中你尝试fscanf()到一个NULL指针,并且还会泄漏分配的内存。

linescolum(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个字符字符串及其预定的rowcolumn位置{1}}矩阵,虽然创建一个部分填充的矩阵没有任何问题,但你采取的方法有几个麻烦点。

正如所指出的,检查40 x 40是不正确的。 fscanf(...) != EOF)系列函数返回的匹配计数等于根据 format-string 发生的成功转化次数。例如,使用格式字符串Xscaf匹配计数(以及"%s %d %d"的{​​{1}}),以便成功读取和转换一行进入returnfscanfstring将是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

其次,您需要检查40while (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时,intsize_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;
}