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()
добавляет копию строки с нулевым символом в конце s2 в конец строки с нулевым символом в конце s1, а затем добавляет завершающий `\ 0 '.
Вы добавляете символ (не строку с завершающим NUL!) К строке, которая может или не может быть завершена NUL. Единственное время, когда я могу представить эту работу в соответствии с описанием страницы руководства, - это если каждый символ в файле оканчивается 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! */
person
Michael
schedule
08.01.2010
strcat
объединяет строки. Даже если&symbol
являетсяchar *
, он не заканчивается нулем. Вы должны использоватьfgets
илиfread
. Кроме того,strcat
в любом случае будет медленным в вашем случае, потому что он сканируетsource
каждый раз, когда ему нужно добавить один символ. - person Alok Singhal   schedule 08.01.2010fread
. - person Nick Meyer   schedule 08.01.2010fread()
по-прежнему хорошая идея, хотя - person Christoph   schedule 08.01.2010&symbol
завершается нулем, еслиsymbol
является int, и вы используете архитектуру с прямым порядком байтов. Но не то, на что я бы хотел положиться. - person Mark Ransom   schedule 08.01.2010sizeof(int) == 1
? Как вы сказали, на это лучше не полагаться. - person Alok Singhal   schedule 08.01.2010