char source[1000000];
FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
while((symbol = getc(fp)) != EOF)
{
strcat(source, &symbol);
}
fclose(fp);
}
这段代码有很多问题:
- 它非常慢(你一次只能提取一个字符的缓冲区)。
- 如果文件大小超过
sizeof(source)
,那么会存在缓冲区溢出的风险。
- 实际上,当你仔细看它时,这段代码根本不应该工作。如手册中所述:
strcat()
函数将一个以 null 结尾的字符串 s2 复制到另一个以 null 结尾的字符串 s1 的末尾,然后添加一个终止符 `\0'。
你正在将一个字符(而不是以 null 结尾的字符串!)附加到一个可能没有以 null 结尾的字符串上。我唯一能想象这按照手册描述的工作方式的情况是,如果文件中的每个字符都已经以 null 结尾,那么这就毫无意义了。因此,这绝对是对 strcat()
的可怕滥用。
以下是两种可以考虑使用的替代方案。
如果您事先知道最大的缓冲区大小:
#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++] = '\0';
}
fclose(fp);
}
否则,如果您没有:
#include <stdio.h>
#include <stdlib.h>
char *source = NULL;
FILE *fp = fopen("foo.txt", "r");
if (fp != NULL) {
if (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);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0';
}
}
fclose(fp);
}
free(source);
strcat
连接字符串。即使&symbol
是一个char *
,它也没有以null结尾。你应该使用fgets
或fread
。此外,在您的情况下,strcat
无论如何都会很慢,因为每次需要附加一个字符时,它都会扫描source
。 - Alok Singhalfread
要慢得多了。 - Nick Meyerfread()
仍然是个好主意。 - Christophsizeof(int) == 1
怎么办?正如你所说,最好不要依赖它。 - Alok Singhal