【问题标题】:Broken files in CC中损坏的文件
【发布时间】:2021-01-16 03:35:57
【问题描述】:

我制作了一个简单的脚本来将一个文件内容重写到另一个文件中。 代码如下:

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

int main()
{
    char filename[1024];
    scanf("%s", &filename);

    // printf("Filename: '%s'\n", filename);

    int bytesToModify; scanf("%d", &bytesToModify);

    FILE *fp;

    fp = fopen(filename, "r");
    fseek(fp, 0, SEEK_END);
    int fSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    printf("%d\n", fSize);

    char *buf = malloc(fSize*sizeof(char));

    for (int i = 0; i < fSize; i++) {
        buf[i] = getc(fp);
    }
    fclose(fp);

    FILE *fo;

    fo = fopen("out_file.txt", "w");
    for (int i = 0; i < fSize; i++) {
        fwrite(&buf[i], 1, 1, fo);
    }
    fclose(fo);

    return 0;
}

即使是这样的小文件,我也能看到工件。西里尔字母 sybmol 'я' 出现在文件末尾。 如果我尝试重写可执行文件,我会得到:

99% 的文件只是转向这些符号。我的代码有什么问题?

我正在使用带有 GCC 编译器版本 10.1.0 的 CodeBlocks。 我的操作系统是 Windows 10。

感谢您的帮助。

【问题讨论】:

  • fp = fopen(filename, "r"); ==> fp = fopen(filename, "rb");"out_file.txt"类似
  • ftell的返回值必须是long,而不是int。迭代器 i 也是如此。
  • 无论何时执行任何类型的 IO,您都需要注意观察通过 locale 设置的编码。有效的 locales on windows 有点时髦但仍然有效。

标签: c windows file stdio


【解决方案1】:
  1. 您没有以二进制模式打开文件:"rb""wb"。因此,fgetc 会将所有\r\n 转换为单个\n

  2. 对于每个行终止符,读取的字符少一个。然而您仍然尝试阅读,fgetc 将返回 EOF(和 fgetc returns an int, not char)。由于 EOF 在 Windows 上的值为 -1,当写入转换为 unsigned char 的文件时,这会导致您在记事本中使用的编码中的 Я(很可能是 Windows-1251)。

此外,既然您使用的是fwrite,那么您同样可以使用fread。并且不需要读取,写入字符一次一个,只需使用

char *buf = malloc(fSize);
int bytesRead = fread(buf, 1, fSize, fp); 
fclose(fp);

int bytesWritten = fwrite(buf, 1, bytesRead, fo);

【讨论】:

    猜你喜欢
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2021-04-17
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多