2015-09-21 2 views
-1

Я пытаюсь взять пользовательский ввод с консоли без использования стандартных классов библиотеки C++. Вот мой кодПринимая пользовательский ввод в C++ без стандартных классов библиотеки C++

while(true){ 
     std::string line = " "; 

     while (getline(std::cin, line)) { 

      std::string arr[100]; 
      int i = 0, len = 0; 
      for (int j=0; j < line.length(); j++) { 
       if(line[j] ==' ' || line[j] == '\n'){ 
        std::string word = line.substr(i, j); 
        arr[len] = word; 
        len++; 
        i = j; 
       } 
      } 
      for (int k = 0; k <len ; ++k) { 
       std::cout<<arr[k]<<std::endl; 
      } 

     } 

     //break; 
    } 

Идея состоит в том, чтобы идентифицировать каждое слово и хранить его в массиве. Однако эта программа только идентифицирует первое слово. Любая идея, что я делаю неправильно здесь.

+2

Как вы относитесь к струнному потоку? – Beta

+0

Если вы не хотите использовать STL, почему бы не использовать простой код C? 'scanf' и' printf'. Просто включите заголовок 'stdio.h', и вы должны быть готовы к работе ... – Nidhoegger

+0

Если вы * не можете * использовать' std :: vector', то вам нужно убедиться, что вы не выходите за пределы массива , Но вы * должны * использовать 'std :: vector'. – crashmstr

ответ

1

При чтении этого, кажется, ваша проблема лежит на линии std::string word = line.substr(i, j);. Вы должны понимать, что аргументы substr не «от i до j», а «от i, j символов». Read the documentation. :)

Я не проверял это, поэтому он может быть не идеальным, но принцип есть.

while(true){ 
     std::string line = " "; 

     while (getline(std::cin, line)) { 

      std::string arr[100]; 
      int num_chars = 0, word = 0; 
      for (int i=0; i < line.length(); i++) { 
       /*We increment i, so every non-space character is one we 
       * will include in the word.*/ 
       num_chars++; 
       if(line[i] ==' ' || line[i] == '\n'){ 
        /*We want all characters from i to i+num_chars, that is 
        * we want all characters from j, forward i indices. 
        */ 
        std::string word = line.substr(i, num_chars); 
        arr[word] = word; 
        word++; 
        //We reset i here, in prep for parsing the next word. 
        i = 0; 
       } 
      } 
      for (int k = 0; k <len ; ++k) { 
       std::cout<<arr[k]<<std::endl; 
      } 

     } 

     //break; 
    } 

Две другие соображения:

1) Берегись односимвольные переменные, как это делает его гораздо труднее читать ваш код позже. i является стандартным для цикла я terator или я NDEX с j быть следующий когда вы вложенности для петель. Однако i не подходит для «длины слова». Аналогично, len не подходит для индекса хранимого слова. Я изменил переменные в коде, чтобы было легче читать.

2) Я бы серьезно подумал о пересмотре структуры петли. while является общим и очень полезным, но он также очень подвержен бесконечным циклам. Фактически, while(true) Бесконечный цикл, поэтому, если вы не достигнете break по любой причине, вы столкнетесь с серьезными проблемами.

-

Я также согласен, что, если вы хотите, чтобы избежать «СТЛ» (и, на самом деле std:: и stl являются часто путают, но не то же самое ... так скажем, вы хотите избегайте std), вы должны избегать std::string и std::cin. Используйте C-строки и scanf/printf вместо этого, как предложил Нидхёггер. Он более эффективен, чем параметры std, но он также более подвержен ошибкам и «неопределенным поведением», характерным для C. Это потребует больше усилий, но даст более эффективный результат, если вы сделаете это правильно.

Пока мы это делаем, я НЕ рекомендую std::stringstream, если ваши другие инструменты не могут хорошо выполнять эту работу. У этого класса серьезные проблемы с производительностью и эффективностью, которые хорошо документированы. Я рекомендую использовать его только в случаях, когда вы пишете свой собственный код с std::string, и это было бы слишком трудоемким или с высокой вероятностью быть неэффективным. Это НЕ один из этих случаев.

+0

Хотя я согласен с вашей оценкой, он отклоняет дело для stringstream. Он жестоко прост в использовании, и нужно сосредоточиться на правильном использовании бизнес-логики, а не на том, чтобы получать данные. Если ничтожество, связанное с получением данных в *, - это бизнес-логика или жестокая неэффективность чрезвычайно обобщенный инструмент, такой как stringstream, мешает выполнению бизнес-логики в рамках требуемых параметров. Для домашней работы бизнес-логика не является кодом, она изучает урок, который должна выполнять домашняя работа. Получите это, учитесь и переходите к следующему заданию. – user4581301

+0

@ user4581301: С одной стороны, да, вы правы. «Делайте это» - это хороший подход. С другой стороны, существует неотъемлемая опасность в привычном комфорте с решением как неэффективное, как 'std :: stringstream'. Интернет изобилует легкомысленными рекомендациями по его использованию, включая многие случаи, когда это будет иметь пагубные последствия для производительности. Нужно научиться делать вещи вручную, как научиться управлять автомобилем с ручным приводом. Если вы знаете, как это сделать, у вас не будет проблем с автоматикой. Кроме того, вы можете лучше различать, когда использовать 'stringstream', а когда NOT to. – CodeMouse92

+0

Весьма вероятно, что единственное несогласие, которое мы можем иметь по этой теме, - это когда преподавать руководство. – user4581301

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