2013-08-11 1 views
1

У меня есть программа, которая принимает символы и считывает их в буфер ограниченного размера (в данном случае 64). Если пользователь вводит более 64 символов, он должен отклонить всю строку ввода, предупредить пользователя, что они ввели слишком много символов, и начать все заново. Если пользователь нажимает ctrl-D, это конец файла, программа должна выйти.Чтение символов в ограниченном размере буфера

Итак, моя конструкция такова: сделайте фактический основной буфер 65 символов, чтобы разместить символ новой строки. Если конечный символ не является символом новой строки, пользователь нажимает ctrl-D, поэтому программа выходит. Если буфер заполнен (т.е. содержит 65 символов), а последний не является символом новой строки, программа предполагает, что было задано слишком много символов, поэтому он переходит в цикл и непрерывно считывает входные данные в буфер до тех пор, пока не будет прочитан буфер в конце с новой строкой (в этом случае он предупреждает пользователя о предельном значении и начинает работу), или он обрезается, не заканчивая новой строкой (в этом случае программа завершается).

Мой вопрос в том, как я могу обрабатывать случай, когда пользователь вводит ровно 65 символов (или некоторое целое число из 65), а затем обращается ctrl-D? Поскольку программа в настоящее время стоит, когда буфер заполнен и не заканчивается в новой строке, он предполагает, что произошел переполнение, но в этом случае я хотел бы, чтобы программа завершилась. Как я могу заставить программу завершить работу после получения скаляра, кратного 65 символам, а затем ctrl-D?

#include <string.h> 
#include <unistd.h> 

#define BUFSIZE (65) 


int main(int argc, char* argv[]) { 
    char* prompt = "myshell->"; 
    char* tooMany = "Max characters (64) exceeded.\n"; 
    int numInput; 
    int done = 0; 
    char input[ BUFSIZE ]; 
    while(!done) { 
     int cont = 0; 

     write(STDOUT_FILENO, prompt, strlen(prompt)); 
     numInput = read(STDIN_FILENO, input, BUFSIZE); 
     if(input[ numInput - 1 ] == '\n') { 
      cont = 1; 
     } else { 
      if(numInput != BUFSIZE) { 
       done = 1; 
       write(STDOUT_FILENO, "\n", strlen("\n")); 
      } else { 
       int spill = 1; 
       while(spill) { 
        numInput = read(STDIN_FILENO, input, BUFSIZE); 
        if(input[ numInput - 1 ] == '\n') { 
         spill = 0; 
         write(STDOUT_FILENO, tooMany, strlen(tooMany)); 
        } else { 
         if(numInput != BUFSIZE) { 
          spill = 0; 
          done = 1; 
          write(STDOUT_FILENO, "\n", strlen("\n")); 
         } 
        } 
       } 
      } 
     } 

     /*done ingesting input. Now do something with it...*/ 
     if(cont) { 
      write(STDOUT_FILENO, input, numInput); 
     } 

    } 
    return 0; 
} 

Constraint: я могу использовать только read и write функции, но ничего не из <stdio.h>.

+1

Я считаю, что вы не должны ограничивать размер строки ввода. Используйте [getline] (http://linux.about.com/library/cmd/blcmdl3_getline.htm) –

+0

@BasileStarynkevitch Да, это сработает, но я могу использовать только системные вызовы для ввода-вывода. – Ataraxia

+0

Затем убедитесь, что вы увеличиваете свой буфер, чтобы всегда соответствовать строке внутри (возможно, используя 'malloc' ...) –

ответ

-3

Если это действительно оболочка, то почему бы не обрабатывать более длинные потоки ввода данных?

Если ваш буфер ограничен 65/64 байт, тогда код «читать/обрабатывать или анализировать текст/читать разбор/и т. Д.». петля.

Когда ваш код получает CTRL-D, тогда выполните результаты всех ваших анализов.

+1

Это ответы «Что такое один способ сделать оболочку?», Но есть ли у вас какие-либо предложения по решению проблемы, о которой я говорил в вопросе о том, как прекратить выполнение при получении ровно 65 байт, за которым следует 'ctrl-D' ? – Ataraxia

+0

@Ataraxia, мы говорим о разнице между программистом и программистом-аналитиком. В то время как программист просто будет делать то, что ему говорят, аналитик будет исследовать требования проблемы и найти самое простое решение, которое обеспечивает наибольшее количество функций. Я не думаю, что ваши пользователи оценят ввод 66 символов информации. и тогда ему будет сказано начать! – JackCColeman

+0

Да, я согласен, что ограничение персонажа слишком мало. Но, к сожалению, конструктивные ограничения не соответствуют мне в этой конкретной ситуации. Поэтому я не могу быть программистом здесь. – Ataraxia

0

Вы должны действительно принять произвольные размеры линий. Обратите внимание, что чтение tty-е. в терминале, отличается от показаний, например. какая-то труба. (Pseudo tty -s - сложная тема: некоторые строки буферизации происходят в ядре).

И у вас должна быть некоторая буферизация - у вас может быть read больше байтов, чем нужно, поэтому сохраняйте дополнительные байты в буфере для будущего потребления.

Значит, вы должны malloc буфер (и перераспределить его при слишком малом). Если преподаватель не разрешил malloc, используйте свой собственный распределитель, используя mmap

Прочтите внимательно справочную страницу read(2). Не забывайте, что он может возвращать -1 при ошибке, 0 в конце файла, или некоторые рассчитывают на успех.

+1

Хорошо, я уточнил вопрос и удалил некоторые отвлекающие элементы (например, упомянул, что это было для оболочки). Я ценю помощь, но я считаю, что я, возможно, не поставил вопрос так ясно, как мог. – Ataraxia

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