gpt4 book ai didi

c - 从文件中精确打印和扫描 (C)

转载 作者:太空宇宙 更新时间:2023-11-04 00:05:00 28 4
gpt4 key购买 nike

我想使用 printArea() 将数组打印到文件中,使用 scanArea() 我想精确地扫描这个文件并将其粘贴到我的数组中。

所以从逻辑上讲,如果我执行 printArea() 和 scanArea(),我应该得到与以前相同的结果?好吧,不。我有一些换行符。对我的代码有什么想法吗?

int m = 0;
int n = 0;
int c = 0;

void printArea (int len, char p[][len])
{
FILE *out = fopen ("spielfeld.txt", "w");
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
fputc(p[i][j], out);
fputc(10, out);
}
fclose(out);
}

int scanArea (int len, char p[][len])
{
FILE *in = fopen ("spielfeld.txt", "r");

if (in == 0)
return 1;
else
{
while ((c=fgetc(in)) != EOF)
{
if ((c=fgetc(in)) == 10)
{
c++;
m++;
n = 0;
}
p[m][n] = (c=fgetc(in));
n++;
}
return 0;
}
fclose(in);
}

调用者:

int len;
len = 12;
char arr[len][len];

showArea (len, arr);
printArea(len, arr);
scanArea (len, arr);
showArea (len, arr);

第一个和第二个showArea不同。

111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111

111111111111
1111
1111111
1111
1111111
1111
1111111
1111
1111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111

最佳答案

scanArea() 中的主循环有问题。目前是:

while ((c=fgetc(in)) != EOF)
{
if ((c=fgetc(in)) == 10)
{
c++;
m++;
n = 0;
}
p[m][n] = (c=fgetc(in));
n++;
}

循环条件读取一个字符。 if 语句立即读取下一个字符,丢弃第一个字符。然后,您又读取了另一个字符以分配给数组,同时也放弃了第二个字符。这意味着您跳过了三分之二的字符。当它是换行符时,您还会增加 c ,这很奇怪且毫无意义。换行应该写成 '\n' 而不是 10。

你需要一些不太热衷于阅读字符的东西:

while ((c = fgetc(in)) != EOF)
{
if (c == '\n')
{
m++;
n = 0;
}
else
p[m][n++] = c;
}

这还是有点危险的;它会将除换行符之外的任意数量的任何类型的字符存储到数组中,而不用担心数组的边界,无论是在单行上还是在总行数上。但它不会跳过三分之二的数据。

进一步查看,我发现 mnc 显示为全局变量;它们应该是 scanArea() 的本地。您应该尽可能避免使用全局变量。必要时,应在文件中将它们设为static,除非它们真的必须在源文件之间共享。那么您需要遵循 How do I use extern to share variables between source files 中的指南以确保一切一致。

There is only one scanArea() and m, n and c are only used there.

那么他们就没有本地化的借口。实际上,如果您两次调用 scanArea(),这些变量是全局变量的事实意味着在第二次调用时,索引将从超出范围的数组位置开始,并且会变得更糟从那里开始。


工作代码

我将函数设置为static,直到证明它们需要在另一个源文件中可见。不是每个人都像我一样对此保持肛门保持。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void printArea(int len, char p[len][len])
{
FILE *out = fopen("spielfeld.txt", "w");
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
putc(p[i][j], out);
putc('\n', out);
}
fclose(out);
}

static int scanArea(int len, char p[len][len])
{
FILE *in = fopen("spielfeld.txt", "r");

if (in == 0)
return 1;
else
{
int m = 0;
int n = 0;
int c;
while ((c = getc(in)) != EOF)
{
if (c == '\n')
{
m++;
n = 0;
}
else if (n >= len || m >= len)
{
fprintf(stderr, "Accessing array out of bounds at p[%d][%d]\n", m, n);
exit(1);
}
else
p[m][n++] = c;
}
}
fclose(in);
return 0;
}

static void showArea(int len, char p[len][len])
{
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
putchar(p[i][j]);
putchar('\n');
}
}

int main(void)
{
int len = 12;
char arr[len][len];
memset(arr, '1', len * len);

puts("Before:");
showArea(len, arr);
printArea(len, arr);
scanArea(len, arr);
puts("After:");
showArea(len, arr);
}

在 Mac OS X 10.10.1(使用 GCC 4.8.1 编译)上运行时,我得到输出:

Before:
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
After:
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111

All works, except my 8th line is completly blank, so now I got 13 lines instead of 12.

我无法解释你空白的第 8 行。

我注意到文件名重复了;重复文件名之类的东西会导致错误。理想情况下,应修改代码,以便将要使用的文件名传递给读写函数,调用代码应提供该名称。然而,这有点超出了当前问题的范围。

另请注意,如果 showArea() 被修改为采用文件流参数 (void showArea(FILE *fp, int len, char p[len][len]) 和 I/O 调用进行了适当的修改,然后 printArea() 中的代码可以修改为打开文件,调用 showArea(),然后关闭文件。

关于c - 从文件中精确打印和扫描 (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27475345/

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