以二进制模式打开文件进行处理

时间:2016-09-28 15:21:39

标签: c file-io

我基本上做的是以二进制模式打开文件,将其转储到缓冲区并处理它,我终于意识到以二进制模式打开文件导致问题,我在谷歌搜索了一下但是我不知道如何解决它。

代码的目的是减少行数。注意:程序的逻辑是正确的。

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

int foo(const char *filename);

int main(void)
{
    foo("file.txt");

    fputs("Press any key to continue...", stderr);
    getchar();
    return 0;
}

int foo(const char *filename)
{
    /* open file in binary mode */
    FILE *fp = fopen(filename, "rb");
    if (!fp) {
        perror(filename);
        return -1;
    }

    /* store file size and allocate memory accordingly */
    long f_size;
    fseek(fp, 0L, SEEK_END);
    f_size = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    char *buf = (char *)malloc(f_size+1);
    if (!buf) {
        puts("Error - malloc failed.");
        return -2;
    }

    /* store file contents in buffer */
    size_t bytes_read = fread(buf, 1, f_size, fp);
    if (bytes_read != f_size) {
        fclose(fp);
        free(buf);
        puts("read error...");
        return -3;
    }
    else {
        fclose(fp);
        buf[f_size] = '\0';
    }

    bool f = 0;
    size_t n = 0;
    size_t m = 0;
    while (buf[n]) {
        if (buf[n] == '\n') {
            if (f) {
                f = 0;
                buf[m++] = '\n';
            }
        }
        else {
            f = 1;
            buf[m++] = buf[n];
        }
        n++;
    }
    /* NUL-terminate buffer at m*/
    buf[m] = '\0';

    /* open file for writing */
    fp = fopen(filename, "wb");
    if (!fp) {
        perror(filename);
        free(buf);
        return -4;
    }

    /* write buffer to file */
    size_t bytes_written = fwrite(buf, 1, m, fp);
    if (bytes_written != m) {
        puts("fwrite error...");
    }
    fclose(fp);
    free(buf);
    return 0;
}

file.txt的:

  

00000000

     

00000000

     

00000000

期望的输出:

  

00000000
  00000000
  00000000

1 个答案:

答案 0 :(得分:3)

如果您正在将文本文件处理为文本,则应以文本模式而不是二进制模式打开它。文本文件和二进制文件之间的物理区别是依赖于系统的,并且在某些系统上没有区别,但是可移植程序需要意识到它至少可能会产生影响。这是关于文件内容的C视图,而不是用于访问内容的(流)函数。

特别是,如果以文本模式打开文件,那么I / O函数将在系统的外部(文本)行终止符的标准约定和内部换行符之间进行转换。如果您的程序对输入文件进行操作,您认为这些文件符合本地系统的行终止概念,并且您希望程序查看其输入文件,其中每行由换行符终止(单独) ,然后您需要以文本模式打开文件以进行该翻译。但请注意,这可能会产生其他影响。

如果您不能或不会以文本模式打开文件,那么您需要建立并处理&#34; line&#34;意味着你的程序。完全可以使它识别不同类型的行终止符,甚至是混合类型的行终止符。在这种情况下,知道Windows文本文件行由双字节序列"\r\n"终止可能是有用的,而Unix行(包括OS X)文本文件由单个换行符终止。经典MacOS文本文件的行由单一回车终止,但您现在可能不需要担心这些。其他一些系统有其他约定或支持多种约定。