2016-01-18 6 views
0

Я работаю над заданием, где часть его читать из стандартного ввода с помощью системной функции read(), а затем распечатать последние 10 строк и до сих пор я получил это:Сегментация ошибка при чтении с чтением

int tailSTD() 
{ 
    char *lines = malloc(1); 
    char buffer[10]; 
    int cmdCount = 0, buffCount, rState; 
    while((rState = read(STDOUT_FILENO, buffer, 10)) > 0) 
    { 
     if(rState < 0) 
     { 
      if(errno == EINTR) rState = 0; 
      else 
      { 
       perror("read()"); 
       return 0; 
      } 
     } 
     else if (rState == 0) break; 

     lines = realloc(lines, strlen(lines) + strlen(buffer)); 
     for(buffCount = 0; buffCount < strlen(buffer); buffCount++) 
     { 
      lines[cmdCount] = buffer[buffCount]; 
      cmdCount++; 
     } 
    } 
    printf("do we get this far?"); 
    printSTDLines(lines); 
    return 0; 
} 

Проблема в том, что я получаю ошибку сегментации где-то вдоль цикла, и я не уверен, где это работает с fgets(), и я просто изменил его только потому, что он просто должен быть выполнен с read(). Это, наверное, очень грязно, за что я извиняюсь, но это нужно делать именно так. Я знаю, проблема здесь, потому что она никогда не доходит до последнего printf до printSTDLines. Вот printSTDLines, если вам это нужно:

void printSTDLines(char *lines) 
{ 
    int lineCount = strlen(lines), newLineCount = 0; 
    while(newLineCount < 10) 
    { 
     if(lines[lineCount] == '\n') 
     { 
      newLineCount++; 
     } 
     lineCount--; 
    } 
    int readSize = strlen(lines) - lineCount; 
    for(lineCount = readSize; lineCount < sizeof(lines); lineCount++) 
    { 
     write(STDOUT_FILENO, &lines[lineCount], 1); 
    } 
} 
+0

Где находится 'printSTDLine()'? –

+0

вот что, эта функция (теперь исправлена) не работает для 'stdin', поэтому я начал версию' stdin' с нуля, если у вас есть идея, как получить эту другую версию для stdin, я рад слышать – Reaper9806

+0

Ваша проблема в том, что 'buffer' содержит строку. – immibis

ответ

1

Вы используете strlen(lines), но вы никогда не nul прекратить его действие. strlen() функция рассчитывает найти '\0' байт, чтобы сказать, где конец «строки», вы не добавить, что байт в любой из ваших массивов и что вызывает неопределенное поведение, один из возможных последствий этого является ошибка сегментации.

Кроме того, этот

for(lineCount = readSize; lineCount < sizeof(lines); lineCount++) 

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

Чтобы использовать длину массива внутри printSTDLine(), вам необходимо передать его в качестве параметра.

+0

Да, я всегда путаю 'sizeof' и' strlen' при первом обращении кодирования, и мне всегда нужны годы, чтобы понять, что это проблема, но где в цикле я должен «nul» завершить строку? – Reaper9806

+0

Не имеет значения где. Когда вы передаете его в 'strlen()', он ДОЛЖЕН иметь '' \ 0''. На практике это должно быть после последнего персонажа. –

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