gpt4 book ai didi

c - 读取矩阵的字符串和整数

转载 作者:行者123 更新时间:2023-11-30 17:06:30 26 4
gpt4 key购买 nike

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

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矩阵中的预期column40 x 40位置,尽管创建部分字符串没有错填充矩阵,您所采用的方法存在多个问题点。

如前所述,检查fscanf(...) != EOF)不正确。 Xscaf函数系列返回的匹配计数等于根据您的格式字符串进行的成功转换次数。例如,使用格式为"%s %d %d"的字符串,成功读取并将行转换为returnfscanfstring的匹配计数(因此为linescolumns)将是3return的正确用法是检查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++;
}


其次,您需要对照 lines40检查 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);


(您还需要确认从文件读取的 linescolumns是从零开始还是从一开始)

最后,无需动态声明 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的目的是 linescolumns不能否定的。选择适当的类型可使编译器提供其他警告)

编译

始终在启用警告的情况下进行编译。例:

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com