2016-10-28 11 views
-2

Я пытаюсь эмулировать команду tail в C, но у меня есть проблема.C - Чтение с клавиатуры (контролируется Ctrl + D)

Мне нужно прочесть некоторые строки с клавиатуры (STDIN) (мне все равно, сколько строк). Это чтение будет прервано при нажатии Ctrl + d. Я сделал эту функцию, но она не работает.

int tail(int N) 
{ 
    int i, j, c; 
    char ** lines; 
    /* Char matrix dynamic declaration */ 
    lines=NULL; // Char matrix declaration 
    lines=malloc(N*sizeof(char *)); 
    for (i=0; i<N; i++){ 
     lines[i]=malloc(80 * sizeof(char)); 
    } 
    i=0; 
    while (true){ // I tried this loop, but doesn't work 
     /* This works. Lanes reading from the user's keyboard */ 
     if(i>=N){ 
      for(j=0; j<=N; j++){ 
       if (j<(N-1)) 
        lines[j]=lines[j+1]; 
      } 
      scanf(" %[^\n]", lines[N-1]); 
     }else{ 
      scanf(" %[^\n]", lines[i]); 
     } 
     i++; 
     /* ------------------------------------ */ 
     c=getchar(); // This doesn't work 
     if(c==EOF) 
     goto end; 
    } 
end: 
    for (i=0; i<N; i++){ 
     printf("%s\n", lines[i]); // Showing those lanes 
     free(lines[i]); // Free memory 
    }  
    free(lines); 
    lines = NULL; 

    return 0; 
} 

Моя проблема в том, чтобы читать строки клавиатуры пользователя и одновременно читать ctrl + d. Когда я запускаю функцию, она позволяет мне писать некоторые строки, но она не обнаруживает, когда я нажимаю Ctrl + D. Как я могу это сделать?

EDIT:

Я попробовал новый метод захвата Ctrl + d и теперь моя программа заканчивается, но у меня есть некоторые проблемы. Вот новый код:

int tail(int N) 
{ 
    int i, j, k, c; 
    char ** lines; 

    lines=NULL; 
    lines=malloc(N*sizeof(char *)); 
    for (i=0; i<N; i++){ 
     lines[i]=malloc(MAXLON * sizeof(char)); 
    } 
    i=0; 
    while (true){ 
     /* Read lines from keyboard. */ 
     if(i<N) 
      scanf(" %[^\n]", lines[i]); 
     else{ 
      for(j=0; j<N-1; j++){ 
       for(k=0; k<MAXLON; k++){ 
        lines[j][k]=lines[j+1][k];  
       } 
      } 
      scanf(" %[^\n]", lines[N-1]); 
     } 
     /* ------------------------------------ */ 
     if((c=getchar())==EOF) break; 
     else i++; 
    } 

    for (i=0; i<N; i++){ 
     printf("%s\n", lines[i]); 
     free(lines[i]); 
    } 
    free(lines); 
    lines= NULL; 

    return 0; 

} 

Прямо сейчас, моя программа захватывает N строк с клавиатуры, пока не нажать 2 раза Ctrl + D, но моя проблема сейчас: Если я пишу 5 строк, которые (с хвостом (3), например, который показывает последние 3 строки):

Line 1 
Line 2 
Line 3 
Line 4 
Line 5 
AND HERE I PRESS 2 TIMES CTRL+D 

функция показывает:

Line 4 
Line 5 
Line 5 

Что не так? Функция должна показать:

Line 3 
Line 4 
Line 5 

Большое вам спасибо!

+1

Есть ситуации, когда 'goto' и метки являются приемлемыми. Использование их для циклов или управления контуром не одно из этих ситуаций. Если вы хотите выйти из цикла, используйте инструкцию 'break'. –

+0

Что касается вашей проблемы, когда вы нажимаете последовательность клавиатуры конца файла, она обычно должна быть на пустой строке. –

+0

Привет! Я тоже пробовал с перерывом, но это не сработало. Когда я написал строку с моей клавиатуры, и я нажал enter, а затем Ctrl + D, функция не закончилась ... –

ответ

0

Пожалуйста, смотрите следующий код в качестве рабочего примера:

#include <stdio.h> 

int main(int argc, char* argvp[]) 
{ 
    char buf[1024]; 

    while(gets(buf)) 
    { 
     printf("Read: %s\n", buf); 
    } 
    if (ferror(stdin)) 
     puts("I/O error when reading"); 
    else if (feof(stdin)) 
     puts("End of file reached successfully"); 
} 

Пожалуйста, обратите внимание, что

  1. Размер входного буфера buf не должен быть жестко
  2. gets устарела и вы должен использовать что-то еще, как fgets
  3. КОНЕЦ-ФАЙЛ не распознается gets в середине линии. Это должен быть символ первой строки. Это так на моем RHEL 7.1, но может отличаться от вашей системы
  4. stdin должен быть заменен на реальный входной дескриптор файла
+0

Я использовал ваш код (не то же самое, просто что-то подобное), чтобы попытаться поймать Ctrl + d из STDIN. Но теперь у меня другая ошибка.Не могли бы вы пересмотреть главный пост, который я редактировал? –

+0

Ваш вызов 'getc()' не требуется. Ваш первый 'Ctrl + D' заканчивает ваш вызов' scanf', а второй 'Ctrl + D' выходит из этой функции. Поскольку последний 'scanf' прерван, содержимое' lines [N-1] 'не изменяется, и вы всегда будете видеть последнюю введенную строку дважды. – GMichael

+0

И есть что-то, что я могу сделать, чтобы исправить это? –