2013-04-08 2 views
1

Я пытаюсь написать редактор потока в C, и мне трудно справляться со строками. После чтения в строках файла я хочу сохранить их локально в массиве строк. Однако, когда я пытаюсь сохранить переменную temp в массив строк StoredEdits, я получаю ошибку segmentation fault (core dumped). Кроме того, если я раскомментирую переменную char* temp2 и сохраню ее в моем массиве как обходной путь, то последнее значение, прочитанное в файле, будет храниться для каждого значения в массиве.Работа со строками в C

Я предполагаю, что это связано с тем, что temp2 является указателем. Я пробовал миллион вещей, таких как malloc'ing и freeing этой переменной после каждой итерации, но ничего не работает.

Любая помощь была бы принята с благодарностью.

 #define MAX_SIZE 100 
     typedef char String[MAX_SIZE]; 
      int main(int argc, char* argv[]){ 
       char** StoredEdits;                                          
       int index, numOfEdits; 
       FILE *EditFile;                                              
       char* temp; 
       //char* temp2;                                                

       StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String));                                   

       /*Check to see that edit file is passed in.*/ 
       if(argc < 2){ 
       printf("ERROR: Edit File not given\n"); 
       return(EXIT_FAILURE); 
       } 

       printf("%s\n",argv[1]); 

       if((EditFile = fopen(argv[1],"r")) != NULL){ 
       printf("file opened\n"); 
       numOfEdits = 0; 
       while(fgets(temp, MAX_STRING_SIZE, EditFile) != NULL){ 
        printf("%d %s",numOfEdits,temp); 
        //temp2 = temp;                                              
        StoredEdits[numOfEdits++] = temp; 
        //StoredEdits[numOfEdits++] = temp; 
        printf("Stored successfully\n"); 
       } 

.......... 

       printf("%d\n",numOfEdits); 
       for(index=0;index<numOfEdits;index++){ 
       printf("%d %s\n",index, StoredEdits[index]); 
       } 
+0

Пожалуйста, [не набрасывайте возвращаемое значение 'malloc()' в C] (http://stackoverflow.com/a/605858/28169). – unwind

ответ

4

Вам необходимо инициализировать температуру, чтобы указать на допустимое хранилище.

temp = malloc(MAX_STRING_SIZE+1); 

Похоже, что вы, возможно, намеревался сделать что-то вроде этого:

String temp; 

с помощью макроса. Это было бы лучше, чем обычный массив символов. И общее название для этого - буфер.

char buffer[MAX_STRING_SIZE+1]; 

Затем, вы должны хранить в массиве, а не сам temp, а новая строка, содержащая копию содержимого. Существует функция POSIX strdup, которая должна быть полезной здесь. Примечание. strdup не является частью стандарта C, но доступен в большинстве размещенных внедрений. Исторически это происходит из филиала BSD.

StoredEdits[numOfEdits++] = strdup(temp); 

Позвольте мне попятный немного, и сказать, что если вы выделения нового хранилища для tempвнутри цикла, то вы должны пропустить strdup, потому что, как говорит Джим Балтер, это будет утечка памяти. Если вы выберете temp вне цикла, то не имеет значения, ставите ли вы его статически (объявляя char []) или динамически (с помощью malloc).


Кстати, эта линия не будет покупать вам много:

typedef char String[MAX_SIZE]; 

почему, увидеть классическую Керниган (The K в K & R) эссе Why Pascal is not my favorite Programming Language.


Также обратите внимание, что мои примеры выше не проверить указатель, возвращенный malloc. malloc может потерпеть неудачу. Когда malloc не работает, он вернет указатель NULL. Если вы попытаетесь сохранить данные через этот указатель, Kaboom!

+0

если вы оба установили 'temp' на результат' malloc' и 'strdup', вы будете утечки памяти. Или используйте 'malloc' и пропустите' strdup', или (лучше, я думаю, потому что он не теряет памяти), используйте буфер в стеке и 'strdup'. –

+0

strpdup! именно то, что я искал. Большое спасибо! – aensm

+0

@JimBalter все равно будет течь, если я освобожу (temp) после каждой итерации? – aensm

3

Вы правы в своей проблеме из-за семантики указателя. Вы должны использовать копию содержимого строки из temp.

char *cpy = malloc(1 + strlen(temp)); 
if (cpy) 
    strcpy(cpy, temp); 
//else handle error 
StoredEdits[numOfEdits++] = cpy; 
+0

Это помечено C. C++ - это другой язык, и ответы в терминах этого языка не подходят. –

+0

О, как смущающе. До сих пор я этого не замечал. Тогда я отредактирую свой ответ. – AlexanderBrevig

+0

К сожалению, мне приходится работать на C, а не на C++, поэтому я не думаю, что использование этого класса строк возможно. Я также попробовал strcpy, но там были и ошибки сегментации. – aensm

0

Другие ответили на причину ошибки.

Но из программы я вижу, что вы попытались выделить двойной массив символов. то вы сохраняете каждую строку, считанную из файла, в массив.

StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String)); 

Если мое предположение верно, то вы должны передать массив в strcpy, как показано ниже.

strcpy(StoredEdits[numOfEdits],tmp); 

, когда у вас есть файл, где каждая строка изменяется в размерах, то лучше идти массив указателей указывает на массив символов.

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