2013-10-01 2 views
0

У меня есть файл, который я хочу прочитать и сохранить данные в массиве символов, который я динамически выделяю для памяти после каждого символа. Я хочу динамически распределять память именно так, как требуется. Вот что у меня есть:Чтение и хранение динамически для массива char

FILE *fp; 
char *data; 
int c=0; 

fp=fopen("home/bob/Downloads/filename", "r"); 
data=malloc(sizeof(char)); 

do{ 
    data[c]=fgetc(fp); 
    printf("data : %c\n", data[c]); 
    c++; 
    data=realloc(data, sizeof(char)+c); 
} while(data[c]!=EOF); 

У меня возникает ошибка сегментации.

+0

Это не имеет смысла, 'EOF' является * не * значением' char', ему нужно 'int'. Посмотрите на [прототип для 'fgetc()'] (http://linux.die.net/man/3/fgetc). – unwind

+0

, но как же использование переменной int хранит данные в файле? некоторый int variable = fgetc (указатель); возвращает данные и сохраняет их в переменной int? – user2644819

+0

Значение из файла - это char, присвоенный int или EOF. Поэтому вам нужно прочитать его в int, а затем проверить, не является ли это EOF, а затем отбросить его на char. – zoska

ответ

2

Проблема, скорее всего, здесь:

while(data[c]!=EOF) 

Помните, что вы увеличитьc внутри цикла, так data[c] является неинициализированной частью памяти вы выделяете. Это означает, что вы продолжаете читать символ по символу, если эти неинициализированные данные не являются (char) -1, что, вероятно, будет значительно выше фактического конца файла.

Вместо попробовать что-то вроде этого:

char *data = NULL; 
size_t c = 0; 

for (;;) 
{ 
    const int ch = fgets(fp); 
    if (ch == EOF) 
     break; /* Error or end of file */ 

    char *tmp = realloc(data, c + 1); 
    if (tmp == NULL) 
     break; /* Could not allocate memory */ 

    data = tmp; 
    data[c++] = ch; 
} 
+1

+1 с некоторыми незначительными изменениями; должен указать, что 'realloc()' также может выйти из строя. – unwind

+0

@unwind Спасибо, обновлено. –

0

Вы выделили ОДИН байт памяти. Этого недостаточно, чтобы прочитать файл.

Я предлагаю использовать stat() с помощью ссылки How do you determine the size of a file in C?, чтобы получить размер, а затем выделить size*sizeof(char).

#include <sys/stat.h> 

off_t fsize(const char *filename) { 
    struct stat st; 

    if (stat(filename, &st) == 0) 
     return st.st_size; 

    return -1; 
} 

{ 
    FILE *fp; 
    char *data; 
    int c=0; 
    off_t size = fsize("home/bob/Downloads/filename") +1; 

    fp=fopen("home/bob/Downloads/filename", "r"); 
    data=malloc(sizeof(char) * size); 

    do{ 
     data[c]=fgetc(fp); 
     printf("data : %c\n", data[c]); 
     c++; 
     data=realloc(data, sizeof(char)+c); 
    }while(data[c]!=EOF); 
} 
1

К тому времени ваша программа пытается оценить следующее условие:

(data[c]!=EOF) 

c уже увеличивается и data[c] таким образом пытается получить доступ к элементу из диапазона data массива, в результате чего неопределенное поведение.

0
do{ 
    data[c]=fgetc(fp); 
    printf("data : %c\n", data[c]); 
    c++; 
    data=realloc(data, sizeof(char)+c); 
}while(data[c]!=EOF); // this should be the location of the seg fault 

Пока (данные [c]) смотрит за конец массива.

ли

}while(data[c - 1]!=EOF); 

или приращение C после проверки

+0

Я попробовал c-1, что имеет смысл, но я все еще получаю ошибку seg. – user2644819

0
data[c]=fgetc(fp); --> This gives seg fault 

Потому что вы приращением как этот c++

data=malloc(sizeof(char)); 

data указывает на память sizeof(char), когда вы делаете c++ тогда data[c] становится UB.

1

Прежде всего, вам придется использовать приведение типа с таНос COz таНос возвращает пустоту *

data=(char*)malloc(sizeof(char)); 

Кроме того, EOF не символ (EOF = -1)

Условие внутри цикла while указывает на еще неинициализированную часть памяти.

int ch; 
while(1) 
{ 
if((ch=fgets(fp))==EOF) 
    break; 
data[c]=ch; 
c++; 
data=realloc(data, sizeof(char)+c); 
} 
+0

Вопрос с меткой C, поэтому отличное возвращение malloc - это плохая практика. С C++ все по-другому. – LostBoy

Смежные вопросы