C - Array of Char Arrays - PullRequest
       26

C - Array of Char Arrays

4 голосов
/ 29 декабря 2011

Я пытаюсь поработать с примером из книги K и R по этой теме, но изо всех сил.

Я хочу получить массив Char Arrays, в котором каждый элемент массива 'Father' указывает на массив символов (строку). По сути, я читаю из файла построчно, сохраняю каждую строку в массиве, а затем пытаюсь сохранить этот массив в другом массиве, который затем можно отсортировать с помощью qsort.

Но я, кажется, никуда не денусь с этим! Любая помощь в моем коде очень ценится, т.е. куда мне идти!

РЕДАКТИРОВАТЬ: Проблема в том, что функция печати не распечатывает мои слова, которые должны быть в массиве массивов, а просто печатает мусор, главная проблема в том, что я не уверен, что я разыменовываю все правильно или нет, правильно ли я добавляю его в массив массивов и т. д.

Привет.

#define MAXLINES 5000 /* max no. lines to be stored */
#define MAXLEN 1000 /* max length of single line */

char *lineptr[MAXLINES];

void writelines(char *lineptr[], int nlines);

int main(int argc, char *argv[]) {
 int nlines = 0, i, j, k;
 char line[MAXLEN];
 FILE *fpIn;
 fpIn = fopen(argv[1], "rb");
 while((fgets(line, 65, fpIn)) != NULL) {
     j = strlen(line);
     if (j > 0 && (line[j-1] == '\n')) {
         line[j-1] = '\0';
     }
     if (j > 8) {
         lineptr[nlines++] = line;
     }
 }  
 for(i = 0; i < nlines; i++)
     printf("%s\n", lineptr[i] );
return 0;    
}

Ответы [ 2 ]

5 голосов
/ 29 декабря 2011

Проблема в том, что line[MAXLEN] - это автоматическая переменная, поэтому каждый раз в цикле while он ссылается на один и тот же массив.Вы должны динамически распределять line каждый раз через цикл while (line = calloc(MAXLEN, sizeof(char)) перед вызовом fgets).В противном случае fgets всегда записывает в одну и ту же ячейку памяти, а lineptr всегда указывает на один и тот же массив.

4 голосов
/ 29 декабря 2011

Дэн определенно обнаружил одну ошибку, идентичное хранилище . Но я думаю, что здесь больше ошибок:

while((fgets(line, 65, fpIn)) != NULL) {

Почему только 65? У вас есть MAXLEN место для работы, вы также можете позволить своему вводу быть немного длиннее.

    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = line;
    }
}

Почему именно j > 8? Вы должны отбрасывать короткие строки? В этом случае не забудьте освободить память для строки, как только вы перейдете к динамическому распределению, которое предлагает Дэн.

Обновление

ott рекомендует strdup(3) - это будет легко встроить в существующую систему:

while((fgets(line, 65, fpIn)) != NULL) {
    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = strdup(line);
    }
}

Дэн рекомендовал calloc(3), это было бы лишь немного больше работы:

line = calloc(MAXLINE, sizeof char);
while((fgets(line, 65, fpIn)) != NULL) {
    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = line;
    line = calloc(MAXLINE, sizeof char);
    }
}

Конечно, оба этих подхода сработают, если не удастся выделить память. Проверка ошибок при распределении памяти всегда хорошая идея. А также во втором механизме есть что-то явно нехорошее.

...