Своеобразная ошибка при чтении и печати строк *char в C

Я только что столкнулся с чем-то действительно странным. В моей строке char (назовем ее word) появляются дополнительные буквы, когда я ее печатаю.
Составная буква зависит от:

  1. длина соответствующего префиксного слова.
  2. количество пробелов после слова.

Я анализирую word из line, который представляет собой всего одну строку из стандартного ввода. Я использую функцию readWord, чтобы получить word из line:

void readWord(char **linePointer, char **wordPointer){
  char *line  = *linePointer;
  char *word = *wordPointer;
  while (!isEndOfLine(line) && isLowerCaseLetter(*line)){
    *word = *line;
    word++;
    line++;
  }
  word++;
  *word = '\0';
  printf("The retrieved word is: %s.\n", *wordPointer)
  *linePointer = line;
}

Мои входы/выходы выглядят так (обратите внимание, что я вызываю функцию readWord ПОСЛЕ того, как позабочусь о insert и пробеле между ними):

// INPUT 1 :
insert foo
insert ba      // several spaces after 'ba'
// OUTPUT 2:
The retrieved word is foo.
The retrieved word is bas.

// INPUT 1 :
insert foo
insert ba      // several spaces after 'bar'
// OUTPUT 2:
The retrieved word is foo.
The retrieved word is bare.

Я думал, правильно ли я распределяю *word, и думаю, да:

root.word = (char *)malloc(sizeof(char *)); //root is my structure

Кроме того, это вряд ли связано с какими-то ошибками переназначения строки word, потому что это совершенно ясно в начале функции readWord().

Спасибо за любую помощь. Это действительно сложная ошибка для меня, и я не знаю, что еще я могу сделать.

ОБНОВЛЕНИЕ

Оказывается, у меня действительно есть некоторые проблемы с выделением/переназначением, поскольку:

//INPUT
insert foo//no spaces
  insert bar                //spaces here
//OUTPUT
word variable before calling readWord function: ' '.
The retrieved word is foo.
word variable before calling readWord function: 'insert foo
'.
The retrieved word is bare.

person Mateusz Piotrowski    schedule 22.04.2015    source источник
comment
Вам нужно выделить достаточно памяти для строки, с которой вы работаете. Вы этого не делаете.   -  person milleniumbug    schedule 22.04.2015
comment
word++ после цикла слишком много   -  person ryanpattison    schedule 22.04.2015
comment
@rpattiso Спасибо! Это правда. Однако word не очищается после первой строки, так что это более чем одна ошибка. Я буду работать над тем, что сказал @milleniumbug.   -  person Mateusz Piotrowski    schedule 22.04.2015
comment
Включите все предупреждения компилятора. Следите за каждым предупреждением об косвенном указателе, например, в этом несоответствии while (!isEndOfLine(line) && isLowerCaseLetter(*line)). И добавьте ; в конце строки printf().   -  person Weather Vane    schedule 22.04.2015


Ответы (1)


Никогда не доверяйте своему вводу, поэтому проверяйте наличие пробелов в начале слова.

Вы увеличиваете слово слишком много, как отмечает @rpattiso.

У меня есть сомнения по поводу вашего распределения памяти (вы не показываете нам весь свой код): root.word = (char *)malloc(sizeof(char *)); выделяет место для указателя на char, но не выделяет место для самих символов. readWord может это сделать.

Должна работать следующая адаптированная версия (обновлена):

void readWord(char **linePointer, char **wordPointer){
    char *line  = *linePointer;
    int i;

    while (!isEndOfLine(line) && !isLowerCaseLetter(*line)) line++; // go to begin of word
    *linePointer= line;
    while (!isEndOfLine(line) &&  isLowerCaseLetter(*line)) line++; // go to end of word

    i= line - *linePointer;                     // allocate room for word and copy it
    *wordPointer= malloc((i+1) * sizeof(char));
    strncpy(*wordPointer, *linePointer, i);
    (*wordPointer)[i]= '\0;

    printf("The retrieved word is: %s.\n", *wordPointer);
    *linePointer = line;
}
person Paul Ogilvie    schedule 22.04.2015
comment
Я вижу большой баг. Я публикую обновление (Ошибка в strncopy) - person Paul Ogilvie; 22.04.2015
comment
На самом деле код не работает для слов длиной в одну букву: insert v выдает segmentation fault 11. Он падает, когда пытается запустить строку *wordPointer[i]= '\0'. - person Mateusz Piotrowski; 23.04.2015
comment
Извините, это должно быть (*wordPointer)[i]= '\0';. - person Paul Ogilvie; 23.04.2015