String tokenizer - странное поведение с проверенным массивом - PullRequest
1 голос
/ 10 апреля 2011

РЕДАКТИРОВАТЬ для включения предложений по кодированию и обновлению вопроса

Мне нужно реализовать функцию переноса слов в программе, и я выбрал жадный алгоритм

//I use fread to take in the file in one bite, the parse the resulting array.  The 
//four lines below are from another function.
char *readBuffer= (char *) malloc(sizeof(char) * fileSize);    
int size= ftell(fp);
rewind(fp);
size_t result= fread(readBuffer, 1, size, fp);

int spaceLeft= termWidth;
int outputLines=0, tempLength, printCount-0;
char *temp, *newLine="\n";

temp= strtok(readBuffer, " "),
fputs(temp, stdout); //prints out a 11, when should be a 1, then exits

while ((outputLines < termHeight) && (temp != NULL)){
    strcat(temp, " ");
    tempLength= strlen(temp);

    if (spaceLeft > tempLength){
      fputs(temp, stdout);
      spaceLeft -= tempLength+1;
    } else {
      strcat(newLine, temp);
      spaceLeft= termWidth-(tempLength);
      outputLines++;
      newLines="\n";
    }
    temp= strtok(NULL, " ");
    printCount+= tempLength //debugger display
  }
}

С помощью этого кода я проверил, что файл правильно прочитан в readBuffer командой fputs(readBuffer, stdout).Тем не менее, первые fputs записывают на экран 11, когда это должно быть 1. Затем он пропускает цикл while и выходит.

OutputLines установлен в 0, а termHeight является результатом termHeight=termios.ws_row-1call.

Если temp выводит значение на экран и (outputLines = 0)> termHeight, как в этом случае значение temp может быть нулевым?

1 Ответ

3 голосов
/ 10 апреля 2011

Часть проблемы может заключаться в том, что fgets получает только одну строку из файла. Справочная страница описывает это.Код, кажется, ожидает, что он читает весь файл.Таким образом, temp будет равен NULL после обработки первой строки (один токен, если в нем нет пробелов).

Не зная ни длины текста, который вы читаете, ни значений termHeight или termWidth,невозможно узнать путь выполнения.Но segfault, вероятно, происходит при вызове strlen() для значения NULL temp после обработки этой строки.Хотя это не полное исправление, оператор while, вероятно, должен использовать && вместо ||:

while ((outputLines > termHeight) && (temp != NULL){

И в зависимости от того, как вы хотите его обработать, вам может потребоваться еще один fgets вызов для чтения следующей строки после strtok возвращает NULL.Или, альтернативно, используйте fread, чтобы получить весь файл за один вызов.

...