2011-12-30 2 views
1

Чувствуйте себя глупым, задавая этот вопрос, так как это должно быть легко, но я не могу понять, что случилось.Загрузить файл в Char * Array

void loadIniIntoMemory() { 

    FILE *fp ; 
    fp = fopen (iniFile, "r"); 
    int ch; 
    int final_line_num = 0; 
    int char_index; 

    char* current_line = (char*) malloc(sizeof(char) * MAX_INI_LINE_LENGTH); 

    while((ch = fgetc(fp)) != EOF) { 

     if(ch == 10) { 

      // new line 
      *(current_line + char_index) = '\0'; 
      char_index = 0; 
      iniFileData[final_line_num] = current_line; 
      final_line_num++; 

     } else { 

      // regular char 
      *(current_line + char_index) = ch; // CAN'T DO THIS, CRASH 
      char_index++; 

      if(ch == 13) { 
       // carriage return 
       continue; 
      } 

     } 

    } 

} 

было некоторое время, так как я сделал C, он выходит из строя на этой линии: *(current_line + char_index) = ch;

Спасибо за любую помощь.

--EDIT--

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

void loadIniIntoMemory() { 

    FILE *fp ; 
    fp = fopen (iniFile, "r"); 
    int ch; 
    final_line_num = 0; 
    int char_index = 0; 

    char* current_line = (char*) malloc(sizeof(char) * MAX_INI_LINE_LENGTH); 

    while((ch = fgetc(fp)) != EOF) { 

     if(ch == '\n') { 

      // new line 
      *(current_line + char_index) = '\0'; 
      char_index = 0; 
      iniFileData[final_line_num] = current_line; 
      final_line_num++; 
      current_line = (char*) malloc(sizeof(char) * MAX_INI_LINE_LENGTH); 

     } else if(ch != '\r') { 

      // regular char 
      *(current_line + char_index) = ch; 
      char_index++; 

     } 

    } 

    iniFileData[final_line_num] = current_line; 

    fclose(fp); 

} 

ответ

3

Для начала, вы не инициализировать char_index, а это означает, что, скорее всего, есть мусор в нем. Если вы не инициализируете его, ваша программа добавит некоторое неизвестное число в указатель current_line.

int char_index = 0; /* initialize to 0 */ 

Во-вторых, немного более "естественный" синтаксис будет:

current_line[char_index] = ... 

В-третьих, вы можете проверить символы без использования их целочисленных эквивалентов:

if (ch == '\n') { 
/* this is the same as "ch == 10" */ 

В-четвертых, вы должны закройте открытый файл до выхода из процедуры:

fclose(fp); 

Наконец, я не уверен, что ch == 13 ('\r') и continue предназначен для обработки, так как continue не эффективно не-оп, но вы, вероятно, не хотите, чтобы скопировать его в данные:

if (ch != '\r') { 
    current_line[char_index] = ch; 
    char_index++; 
    /* or on one line: current_line[char_index++] = ch; */ 
} 

Как и в стороне, мощная функция с (и многих других языков) является switch заявления:

/* substitutes your if...elseif...else */ 
switch (ch) { 
case '\n': 
    current_line[char_index] = '\0'; 
    char_index = 0; 
    iniFileData[final_line_num++] = current_line; 
    break; /* <-- very important, C allows switch cases to fall thru */ 

case '\r': 
    /* do nothing */ 
    break; 

default: 
    /* any character that is not a newline or linefeed */ 
    current_line[char_index++] = ch; 
    break; 
} 
+0

-_- ничего себе, спасибо. Примите в секунду. – jn1kk

+0

Спасибо за дополнительную информацию (ваше редактирование). Я собираюсь реализовать if (ch! = 13) и функцию close (fp). Я использовал только C для очень низкого уровня, то есть мой синтаксис немного отличается. – jn1kk

2

Вы не инициализировать char_index. Я предполагаю, что вы хотите инициализировать его до 0. В C неинициализированная переменная будет содержать мусор. Скорее всего, ваш char_index равен некоторому очень большому числу.

0

И некоторые операционные системы, как и большинство совместимых с POSIX, в частности Linux, предоставляют вам возможность сопоставлять сегмент файлов (возможно, весь файл) в виртуальную память. В Linux, вы могли бы рассмотреть вопрос об использовании mmapsystem call

2

Кроме того, что другие уже отмечали, вы также должны переместить вызов выделения строки буфера в петлю и сразу же после final_line_num++; заявления. В противном случае каждая новая строка, которую вы прочтете, будет переписывать предыдущую строку.

+0

OMG, не могу поверить, я пропустил это. И я думал, что моя функция печати была испорчена! СПАСИБО. – jn1kk

+0

Нет проблем. Я принимаю авансы. C -: = –

+0

Здесь была другая проблема -> не сохраняет последнюю строку, спасибо. – jn1kk