在C中逐块读取文件

时间:2016-03-18 11:29:43

标签: c file file-io io buffer

我想完全按原样将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。任何意见都将不胜感激。

3 个答案:

答案 0 :(得分:1)

您的缓冲区未终止。使用fwrite而不是fprintf:

  fwrite(buffer, 1, length, fout);

你也应该检查错误。因此,将fwrite的返回码与length进行比较,如果不同,则重试剩余字节的写入(如果为正)或通过perror("fwrite")打印相应的错误消息(如果返回码为负)

此外,您可以考虑以二进制模式打开文件,这会导致窗口不同,即将"rb""wb"传递给fopen

最后但并非最不重要的是,不要一次循环并获取一个字符,而是考虑使用fread代替:

length = fread(buffer, 1, MAX, fin);

答案 1 :(得分:1)

这是一个简单的例子。(没有错误检查)

您应该使用fwrite(),因为您要写入文件的字符串不是“以null结尾”。另请注意,“b”模式是使用fopen()指定的,这意味着您要将文件作为二进制文件打开。

#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;
}

答案 2 :(得分:0)

首先,将char buffer[MAX];更改为int buffer[MAX];,将char c;更改为int c;char可以是signed char或{{ 1}},取决于您的实施。在后一种情况下,unsigned char会给c = EOF一个大的正数(无论如何都是无符号的),所以循环永远不会结束。 c大到足以容纳所有角色和EOF。

然后,改变你的

int

fprintf(fout, "%s", buffer);

这是因为fwrite(buffer, 1, length, four); 要求使用C风格的字符串,其结尾为fprintf(fout, "%s", buffer);,但您的'\0'不会被终止。因此,程序将继续复制堆栈中的内容,直到满足buffer,在file2中留下大量垃圾。