用C语言逐块读取文件

3
我希望将file1的内容完全复制到file2中(包括空格和换行符)。我需要逐个小块地复制这些内容(这是一个更大项目的一部分,请耐心等待)。
我尝试了以下方法:
#include <stdio.h>
#include <stdlib.h>

#define MAX 5

int main(int argc, char *argv[]) {
    FILE *fin, *fout;
    char buffer[MAX];
    int length;
    char c;

    if((fin=fopen(argv[1], "r")) == NULL){
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    if((fout=fopen(argv[2], "w")) == NULL){
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    while(1){
        length = 0;
        while((c = fgetc(fin)) != EOF && length < MAX){
            buffer[length++] = (char) c;
        }
        if(length == 0){
            break;
        }
        fprintf(fout, "%s", buffer);
    }
    fclose(fout);
    fclose(fin);
}

然而,这会导致我文件2的输出不正确。欢迎提供任何意见。

getc(以及 getcharfgetc)返回的是 int 而不是 char。**int c**。 - Antti Haapala -- Слава Україні
这不是通过使用(char) c进行类型转换来“固定”吗? - user4332327
https://dev59.com/g1sW5IYBdhLWcg3wI0RH - Antti Haapala -- Слава Україні
3个回答

1
您的缓冲区没有以零结尾。请使用fwrite而不是fprintf:
  fwrite(buffer, 1, length, fout);

你应该检查错误。因此,将fwrite的返回值与length进行比较,如果不同,则重试剩余字节的写入(如果是正数),或通过perror("fwrite")打印适当的错误消息(如果返回值为负数)。
此外,您可以考虑以二进制模式打开文件,在Windows上会有所不同,即向fopen传递"rb""wb"
最后但并非最不重要的是,不要循环并一次获取一个字符,而应考虑使用fread
length = fread(buffer, 1, MAX, fin);

1
这里有一个简单的示例(没有错误检查)。
由于您要写入文件的字符串不是“null-terminated”,因此应该使用fwrite()。另外请注意,使用fopen()指定了“b”模式,这意味着您想将文件作为二进制文件打开。
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
#define FILE_BLOCK_SIZE 50
int _tmain(int argc, _TCHAR* argv[])
{
    FILE *fin, *fout;
    unsigned char *BufContent = NULL;
    BufContent = (unsigned char*) malloc(FILE_BLOCK_SIZE);
    size_t BufContentSz;

    if((fin=fopen("E:\\aa.txt", "rb")) == NULL){
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    if((fout=fopen("E:\\bb.txt", "wb")) == NULL){
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    while ((BufContentSz = fread(BufContent, sizeof(unsigned char), FILE_BLOCK_SIZE, fin)) > 0) 
    {
        fwrite(BufContent, sizeof(unsigned char), BufContentSz, fout);
    }

    fclose(fout);
    fclose(fin);

    delete BufContent;
    return 0;
}

0
首先,将 char buffer[MAX]; 更改为 int buffer[MAX];,将 char c; 更改为 int c;,因为 char 可以是 signed char 或者 unsigned char,这取决于你的实现。在后一种情况下,c = EOF 将会给 c 一个很大的正数(它无论如何都是无符号的),因此循环永远不会结束。然而,int 类型的变量足够大,可以容纳所有字符和 EOF。
接下来,修改你的
fprintf(fout, "%s", buffer);

fwrite(buffer, 1, length, four);

这是因为fprintf(fout, "%s", buffer);要求传入以'\0'结尾的C风格字符串,但你的buffer并没有以零结尾。因此,程序会一直复制堆栈中的内容,直到遇到一个'\0'字符,从而在文件2中留下许多垃圾。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接