将文本文件读入 C 缓冲区的正确方法? [英] Correct way to read a text file into a buffer in C?

查看:23
本文介绍了将文本文件读入 C 缓冲区的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理我想在处理它们时读入缓冲区的小文本文件,所以我想出了以下代码:

<代码>...字符源[1000000];FILE *fp = fopen("TheFile.txt", "r");如果(fp != NULL){而((符号= getc(fp))!= EOF){strcat(源代码,&符号);}fclose(fp);}...

这是将文件内容放入缓冲区的正确方法还是我滥用了strcat()?

然后我这样遍历缓冲区:

for(int x = 0; (c = source[x]) != ''; x++){//处理字符}

解决方案

char source[1000000];FILE *fp = fopen("TheFile.txt", "r");如果(fp != NULL){而((符号= getc(fp))!= EOF){strcat(源代码,&符号);}fclose(fp);}

这段代码有很多问题:

  1. 它非常慢(您一次提取一个字符的缓冲区).
  2. 如果文件大小超过 sizeof(source),这很容易导致缓冲区溢出.
  3. 真的,当你更仔细地观察它时,这段代码根本不应该工作.如手册页所述:

<块引用><块引用>

strcat() 函数将空终止字符串 s2 的副本附加到空终止字符串 s1 的末尾,然后添加一个终止`'.

您将一个字符(不是以 NUL 结尾的字符串!)附加到一个可能以或不以 NUL 结尾的字符串中.唯一时间,根据手册页的描述,如果文件中的每个字符都以 NUL 结尾,我可以想象这种工作是否有效,在这种情况下,这将毫无意义.所以是的,这绝对是对 strcat() 的严重滥用.

以下是可以考虑使用的两种替代方法.

如果您提前知道最大缓冲区大小:

#include #define MAXBUFLEN 1000000字符源[MAXBUFLEN + 1];FILE *fp = fopen("foo.txt", "r");如果(fp != NULL){size_t newLen = fread(source, sizeof(char), MAXBUFLEN, fp);如果 ( ferror( fp ) != 0 ) {fputs("读取文件出错", stderr);} 别的 {源[newLen++] = '';/* 只是为了安全.*/}fclose(fp);}

或者,如果您不这样做:

#include #include 字符 * 源 = NULL;FILE *fp = fopen("foo.txt", "r");如果(fp != NULL){/* 转到文件末尾.*/如果(fseek(fp,0L,SEEK_END)== 0){/* 获取文件的大小.*/long bufsize = ftell(fp);if (bufsize == -1) {/* 错误 */}/* 将我们的缓冲区分配到那个大小.*/source = malloc(sizeof(char) * (bufsize + 1));/* 回到文件的开头.*/if (fseek(fp, 0L, SEEK_SET) != 0) {/* 错误 */}/* 将整个文件读入内存.*/size_t newLen = fread(source, sizeof(char), bufsize, fp);如果 ( ferror( fp ) != 0 ) {fputs("读取文件出错", stderr);} 别的 {源[newLen++] = '';/* 只是为了安全.*/}}fclose(fp);}免费(来源);/* 不要忘记稍后调用 free()!*/

I'm dealing with small text files that i want to read into a buffer while i process them, so i've come up with the following code:

...
char source[1000000];

FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
    while((symbol = getc(fp)) != EOF)
    {
        strcat(source, &symbol);
    }
    fclose(fp);
}
...

Is this the correct way of putting the contents of the file into the buffer or am i abusing strcat()?

I then iterate through the buffer thus:

for(int x = 0; (c = source[x]) != ''; x++)
{
    //Process chars
}

解决方案

char source[1000000];

FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
    while((symbol = getc(fp)) != EOF)
    {
        strcat(source, &symbol);
    }
    fclose(fp);
}

There are quite a few things wrong with this code:

  1. It is very slow (you are extracting the buffer one character at a time).
  2. If the filesize is over sizeof(source), this is prone to buffer overflows.
  3. Really, when you look at it more closely, this code should not work at all. As stated in the man pages:

The strcat() function appends a copy of the null-terminated string s2 to the end of the null-terminated string s1, then add a terminating `'.

You are appending a character (not a NUL-terminated string!) to a string that may or may not be NUL-terminated. The only time I can imagine this working according to the man-page description is if every character in the file is NUL-terminated, in which case this would be rather pointless. So yes, this is most definitely a terrible abuse of strcat().

The following are two alternatives to consider using instead.

If you know the maximum buffer size ahead of time:

#include <stdio.h>
#define MAXBUFLEN 1000000

char source[MAXBUFLEN + 1];
FILE *fp = fopen("foo.txt", "r");
if (fp != NULL) {
    size_t newLen = fread(source, sizeof(char), MAXBUFLEN, fp);
    if ( ferror( fp ) != 0 ) {
        fputs("Error reading file", stderr);
    } else {
        source[newLen++] = ''; /* Just to be safe. */
    }

    fclose(fp);
}

Or, if you do not:

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

char *source = NULL;
FILE *fp = fopen("foo.txt", "r");
if (fp != NULL) {
    /* Go to the end of the file. */
    if (fseek(fp, 0L, SEEK_END) == 0) {
        /* Get the size of the file. */
        long bufsize = ftell(fp);
        if (bufsize == -1) { /* Error */ }

        /* Allocate our buffer to that size. */
        source = malloc(sizeof(char) * (bufsize + 1));

        /* Go back to the start of the file. */
        if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }

        /* Read the entire file into memory. */
        size_t newLen = fread(source, sizeof(char), bufsize, fp);
        if ( ferror( fp ) != 0 ) {
            fputs("Error reading file", stderr);
        } else {
            source[newLen++] = ''; /* Just to be safe. */
        }
    }
    fclose(fp);
}

free(source); /* Don't forget to call free() later! */

这篇关于将文本文件读入 C 缓冲区的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆