【问题标题】:Read file block by block in C在C中逐块读取文件
【发布时间】:2016-07-05 03:21:26
【问题描述】:

我想将 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);
}

但是,这会导致我的 file2 输出不正确。任何意见将不胜感激。

【问题讨论】:

标签: c file file-io io buffer


【解决方案1】:

您的缓冲区不是以零结尾的。使用 fwrite 代替 fprintf:

  fwrite(buffer, 1, length, fout);

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

此外,您可以考虑以二进制模式打开文件,这会在 Windows 上造成差异,即将"rb""wb" 传递给fopen

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

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

【讨论】:

    【解决方案2】:

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

    您应该使用 fwrite(),因为您要写入文件的字符串不是“以空值结尾的”。还要注意,“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;
    }
    

    【讨论】:

      【解决方案3】:

      首先,将char buffer[MAX]; 更改为int buffer[MAX];,将char c; 更改为int c;char 可以是signed charunsigned char,具体取决于您的实现。在后一种情况下,c = EOF 会给c 一个很大的正数(反正它是无符号的),所以循环永远不会结束。 int 足够大,可以容纳所有字符和 EOF。

      然后,改变你的

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

      fwrite(buffer, 1, length, four);
      

      这是因为 fprintf(fout, "%s", buffer); 调用 C 风格的字符串,以 '\0' 结尾,但您的 buffer 不是以零结尾的。结果,程序会不断复制堆栈中的内容,直到遇到'\0',在file2中留下大量垃圾。

      【讨论】:

        猜你喜欢
        • 2012-06-22
        • 2022-01-25
        • 2010-12-24
        • 2010-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多