Завершение многострочного пользовательского ввода? - PullRequest
0 голосов
/ 24 сентября 2010

возникли проблемы с недавним проектом. Цель здесь состоит в том, чтобы иметь возможность ввести несколько строк текста, содержащих дату в формате мм / дд / гггг, затем пробел и затем описание события. Я выполнил фактически возможность ввода нескольких строк текста (я думаю), но теперь я не совсем уверен, как это остановить. Есть ли способ просто предположить, что через определенное время, возможно, пользователь завершил ввод? Эта проблема меня сильно беспокоит, так как они никогда не обращались к тому, как завершить ввод данных пользователем, а только к тому, как выполнить несколько строк. Мы должны использовать стандартный пользовательский ввод, а не из текстовых файлов, что было бы намного проще. Код ниже, пожалуйста, не стесняйтесь также сказать мне, если я совершил незамеченную ошибку в другом месте. Мне просто нужно позволить пользователю завершить ввод, чтобы программа могла переупорядочить события [] и вывести их.

calendar.cpp

#include <string>
#include <sstream>
#include <iostream>
#include <vector>

using namespace std;
#include "event.h"


int main(){
 // Maximum number of input lines
 const int MAX = 100; 

 // Array of pointers to events 
 Event *events[MAX];

 // Number of currently used pointers in events
 int size = 0;
 int i = 0;

 // Vector containing each input line as a string
 vector<string> vec (100);
 char temps[100];
 while(i < MAX){
  cin.getline(temps, 100);
  vec[i] = temps; 
  i++;
 }


 for(int i = 0; i < vec.size(); i ++){
   int found = vec[i].find("/");
   int tmo = atoi(vec[i].substr(0, found).c_str());
   int sfound = vec[i].find("/", found + 1, 6);
   int tda = atoi(vec[i].substr(found + 1, sfound - (found + 1)).c_str());
   int tye = atoi(vec[i].substr(sfound + 1, 4).c_str());
   string tdes = vec[i].substr(sfound + 6, vec[i].length() - (sfound + 6));
   events[size] = new Event(tmo, tda, tye, tdes);
   size++;
 }

 return 0;
}

event.cpp

#include <iostream>
#include <string>

using namespace std;
#include "event.h"

Event::Event(int mo, int da, int ye, string des){
 month = mo;
 day = da;
 year = ye;
 desc = des;
}

Event::~Event(){

}

void Event::print(){
 cout << month << "/" << day << "/" << year << " " << desc << endl;
}

event.h

#ifndef EVENT_H
#define EVENT_H

#include <iostream>
#include <string>
using namespace std;

class Event{
 public:
  Event(int mo, int da, int ye, string des);
  ~Event();
  void print();
 private:
  int month;
  int day;
  int year;
  string desc;
};

#endif

Заранее благодарю за помощь.

EDIT:

Замена цикла while () на:

while ((i < MAX) && (!cin.eof()) {
  cin.getline(temps, 100);
  vec[i] = temps; 
  i++;
 }

Выглядит многообещающе, но даже после введения маркера EOF с помощью Ctrl + D (^ D), как было предложено, пользовательский ввод все еще может продолжаться. Любая причина, почему это может происходить?

Ответы [ 3 ]

2 голосов
/ 24 сентября 2010

Один из способов сделать это состоит в том, чтобы пользователь нажимал Ctrl-D, чтобы обозначить конец файла.Вам нужно будет проверить конец файла в цикле.

while ((i < MAX) && (!cin.eof()) {
  cin.getline(temps, 100);
  vec[i] = temps; 
  i++;
 }

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

РЕДАКТИРОВАТЬ:

Ctrl-Z - это нажатие клавиши EOF на компьютерах с Windows.Возможно, Ctrl-Z должен находиться в начале строки в этой ОС (подробнее об этом см. Обсуждение http://www.velocityreviews.com/forums/t356170-cant-detect-eof-from-stdin-on-windows-console.html)

0 голосов
/ 24 сентября 2010

Вы должны дать пользователю escape-символ для выхода из цикла.


//you should probably prompt the user.
 //some testing may be in order to determine the end of line sequence
 //could be \r\n or \n depending on OS, iirc
 string escape("**\r\n");
 const char * escape_ptr = escape.c_str();
 cout << "Please enter ** on one line to quit." << endl;
 vector<string> vec (100);
 char temps[100];
 while(i < MAX){
  cin.getline(temps, 100);
  vec[i] = temps;

  if (strncmp(temps,escape_ptr,4) == 0) {
     break; //the escape sequence was typed.
  }

  i++;
 }

0 голосов
/ 24 сентября 2010

Как правило, вам нужно, чтобы пользователь набрал что-то, что распознает их ввод.Например, в mail заголовок отличается от тела пустой строкой.Вы можете подумать о том, чтобы потребовать от пользователя иметь две пустые строки или какую-нибудь текстовую строку, например «END» или «», или подождать, пока вы не увидите другую дату, которая неявно обозначает начало следующего события.

Если вам действительно нужны тайм-ауты ... большинство ОС имеют функцию select(), которая может ожидать дескриптор файла stdin, и тайм-аут, если в течение некоторого времени не происходит никаких событий чтения / исключения.Кроме того, вы можете заблокировать чтение и установить таймер (например, alarm (2), setitimer () в Linux).

(Кроме того, стоит научиться писать потоковые операторы для ваших классов, но этодостаточно большая тема, в которую я не буду вдаваться в подробности. Вам также следует рассмотреть возможность использования push_back (), чтобы поместить строки ввода в ваш вектор, а не создавать его со множеством пустых строк и разбрасывать над ними.Не нужно использовать «100» и MAX, но можно просто позволить «расти естественным образом» при обработке ввода.)

...