Ответ 1
char source[1000000];
FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
while((symbol = getc(fp)) != EOF)
{
strcat(source, &symbol);
}
fclose(fp);
}
В этом коде есть несколько ошибок:
- Это очень медленно (вы извлекаете буфер один символ за раз).
- Если размер файла превышает
sizeof(source)
, это подвержено переполнениям буфера. - В самом деле, когда вы смотрите на него более внимательно, этот код не должен работать вообще. Как указано в man-страницах:
Функция
strcat()
добавляет копию строки s2 с нулевым завершением в конец строки s1 с завершающим нулем, затем добавляет завершающий `\ 0 '.
Вы добавляете символ (а не строку с завершающим NUL!) в строку, которая может быть или не быть завершена NUL. Единственный раз, когда я могу представить, что это работает в соответствии с описанием man-страницы, является то, что каждый символ в файле заканчивается NUL, и в этом случае это было бы бессмысленно. Так что да, это, безусловно, ужасное злоупотребление 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'; /* Just to be safe. */
}
fclose(fp);
}
Или, если вы этого не сделаете:
#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++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
free(source); /* Don't forget to call free() later! */