- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将二维字符数组保存到文件中。我的二维数组是一 block 板,我可以在其中绘制、调整大小、删除和添加行/列。
我在将其保存到文件时遇到问题。
首先,我不知道这两个函数中哪一个有问题。有没有办法查找我尝试保存到的 .txt 文件并查看它是否有效?
第二,这是两个函数,SAVE 和 LOAD to .txt 文件。
.txt 文件的名称通过用户的参数传递。请忽略“itreachedhere”打印命令。
void save_board(char* textfile, board* theboard){
FILE* outfile = NULL;
int i,j;
outfile=fopen(textfile, "w");
if(outfile==NULL){
printf("Could not open file %s.\n", textfile);
}
printf("itreachedhere\n");
for(i=0;i<theboard->num_rows;i++){
for(j=0;j<theboard->num_cols;j++){
fprintf(outfile, " %c ", theboard->myboard[i][j]);
}
fprintf(outfile, "\n");
}
fclose(outfile);
}
void load_board(char* textfile, board* theboard){
FILE* infile = NULL;
int i, num_chars=0;
char current_char;
int lengths[10000];
int index=0;
int row=0;
infile=fopen(textfile, "r");
if(infile==NULL){
printf("Could not open file %s.\n", textfile);
// exit(1);
}
while(!feof(infile)){
current_char=fgetc(infile);
num_chars++;
//printf("%d ", num_chars);
if(current_char=='\n'){
// This array stores the length of characters of each line
lengths[index]=num_chars+1;
//update index
index++;
// Increment the number of row read so far
row++;
// Reset the number of characters for next iteration
num_chars=0;
}
}
//printf("%d",lengths[1]);
theboard->num_rows=row;
theboard->num_cols=lengths[0];
//recreate the board
createboard(theboard);
//now we need to copy the characters in infile to myboard
for(i=0;i<theboard->num_rows;i++){
fgets(theboard->myboard[i],(lengths[i]+1),infile);
//printf("%c", theboard->myboard[i][0]);
}
printf("itreachedhere\n");
printboard(theboard);
//printf("itreachedhere\n");
fclose(infile);
}
例如。如果我有一 block 尺寸为 4 x 5 的木板
3 * * * * *
2 * * * * *
1 * * * * *
0 * * * * *
0 1 2 3 4
然后我会像这样保存它,
Enter your command: s e.txt
然后像这样加载它,
Enter your command: l e.txt
然后当我尝试打印板时我会得到类似的东西
3 � � � � � � � � � � � � � � � � �
2 � � � � � � � � � � � � � � � � �
1 � � � � � � � � � � � � � � � � �
0 � � � � � � � � � � � � � � � � �
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
我的打印板功能没有任何问题。我认为我的错是我不知道如何正确保存文件或正确检索文件。
感谢您的评论。现在我明白了
2 * * * *
1 * * * *
0 * * * *
0 1 2 3 4 5 6 7 8 9 10 11 12 13
最佳答案
继续评论,我将重点关注您的阅读。重新阅读有关 feof
的行错了。您的情况的简短版本是流错误条件(这就是 feof
所寻找的),直到您调用 fgetc(infile)
才设置。 (此时您已经在循环内并且已更新 num_chars
,即使您在上次循环中读到 EOF
)。
现在让我们谈谈为什么即使您正确使用了EOF
,您的代码仍然会失败。 。当您声明char current_char;
时然后尝试正确测试 while ((current_char = fgetc (infile)) != EOF) {...}
,你永远不会看到EOF
设置比较 char
反对int
。要解决此问题,您的current_char
必须声明为int
.
您阅读时遇到的其他问题。没有理由将每行的字符数存储在 lengths
中数组(除非你有一个锯齿状数组)。在正常的正方形/矩形板表示中,所有行都将具有相同数量的元素。您需要知道的是每行中的字符数,并且需要根据每行的固定数量验证您的读取。
此外,如果您正在读取不包含 '\n'
的板文件怎么办?在最后一行的末尾(称为非 POSIX 行尾/文件尾)。您可以通过简单检查读取的最后一个字符是否确实是 '\n'
来防止出现这种情况。或不。如果不是,那么您需要将行索引增加 1
否则你会丢失数据。 (这意味着您需要保存最后读取的字符以进行比较)
下面是一种将固定长度的未知数量的行/列读取到 lengths
中的方法的简短示例。大批。我用fp
为您infile
和rows x cols
和ncol
用于索引和每行字符比较。我还声明了一个常量 NDATA
而不是使用像 10000
这样的魔数(Magic Number)在代码中。 (这使得调整大小成为一个简单的改变)代码只是从作为程序第一个参数给出的文件名中读取(如果没有给出文件名,则默认从 stdin
读取)尝试以下操作:
#include <stdio.h>
enum { NDATA = 1000 };
int main (int argc, char **argv) {
char lengths[NDATA] = "", last = 0; /* initialize all variables */
int current_char = 0, /* must be int to indicate EOF (-1) */
rows = 0, /* row index */
cols = 0, /* col index */
ncol = 0, /* num cols per-row, must be equal for each row */
ndx = 0; /* lengths index */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open */
fprintf (stderr, "fileio() error: file open failed '%s'\n", argv[1]);
return 0;
}
while ((current_char = fgetc (fp)) != EOF) { /* read each char until EOF */
if (current_char == '\n') { /* if end of line encountered on read */
if (!ncol) /* is ncols set?, if not */
ncol = cols; /* set it */
else if (cols != ncol) { /* otherwise, if not correct - error */
fprintf (stderr, "error: unequal number of cols at row '%d'\n",
rows);
return 1;
}
cols = 0; /* reset column index */
rows++; /* increment row index */
}
else { /* normal char, add to lengths, increment index */
lengths[ndx++] = current_char;
cols++;
}
last = current_char;
if (ndx == NDATA) { /* verify you don't exceed storage */
fprintf (stderr, "warning: lengths array is full.\n");
break;
}
}
if (fp != stdin) fclose (fp); /* close file */
/* protect against non-POSIX end-of-line on last line in file */
if (last != '\n') {
if (!ncol) /* is ncols set?, if not */
ncol = cols; /* set it */
else if (cols != ncol) { /* otherwise, if not correct - error */
fprintf (stderr, "error: unequal number of cols at row *'%d'\n",
rows);
return 1;
}
cols = 0; /* reset column index */
rows++; /* increment row index */
}
printf ("board: %d x %d\n\n", rows, ncol);
for (int i = 0; i < ndx; i++) {
if (i && i % ncol == 0)
putchar ('\n');
printf (" %c", lengths[i]);
}
putchar ('\n');
return 0;
}
板输入文件示例
$ cat dat/board.txt
01234
56789
abcde
fghij
示例使用/输出
$ ./bin/boardread <dat/board_neol.txt
board: 4 x 5
0 1 2 3 4
5 6 7 8 9
a b c d e
f g h i j
查看如何执行读取以及如何完成验证。当您看完面向字符的内容后,请阅读 fgetc
,想想使用 fgets
的面向行输入可以使整个读取变得多么简单。读取每一行,然后简单调用 strlen
验证长度(考虑到 '\n'
在读取中包含 fgets
。如果您有任何问题,请告诉我。
关于c - 如何将位于结构体中的二维数组中的每个字符保存并加载到文件中? C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41007784/
我是一名优秀的程序员,十分优秀!