终止多行用户输入?

时间:2010-09-24 06:47:52

标签: c++ user-input vector

最近的一个项目有点问题。这里的目标是能够输入几行文本,其中包含以mm / dd / yyyy格式表示的日期,后跟空格,然后是事件的描述。我已经完成了允许多行文本输入(我认为),但现在我不确定如何阻止它。是否有一种方法可以在一段时间之后简单地假设用户已完成输入?这个问题给我带来了很大的压力,因为他们从未真正解决过如何结束用户输入,只知道如何完成多行。我们必须使用标准用户输入,而不是文本文件,这将更容易。下面的代码,请随时告诉我,我是否在其他地方发现了一个未被注意的错误。我只需要让用户完成输入,这样程序就可以重新排序事件[]并输出它们。

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

提前感谢您的帮助。

编辑:

用:

替换我的while()循环
while ((i < MAX) && (!cin.eof()) {
  cin.getline(temps, 100);
  vec[i] = temps; 
  i++;
 }

看似很有希望,但即使按照建议用Ctrl + D(^ D)注入EOF标记,用户输入仍然可以继续。有什么理由可能会发生这种情况?

3 个答案:

答案 0 :(得分:2)

实现此目的的一种方法是让用户按Ctrl-D表示文件结束。您必须在循环中检查文件的结尾。

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

此方法的另一个好处是可以将文本文件呈现给程序而不是用户输入,并且在到达文件末尾时将实现相同的结果。

编辑:

Ctrl-Z是Windows机器上的EOF键击。 Ctrl-Z可能必须位于该操作系统的一行的开头(有关此主题的更多信息,请参阅http://www.velocityreviews.com/forums/t356170-cant-detect-eof-from-stdin-on-windows-console.html的讨论)

答案 1 :(得分:0)

通常,您需要用户键入可识别的分隔输入的内容。例如,在mail中,标题通过空行与主体区分开来。您可能会考虑要求用户有两个空行或一些文本字符串,如“END”或“”,或者您可能要等到另一个日期隐含地表示下一个事件的开始。

如果你真的想要超时......大多数操作系统都运行select()函数,可以等待stdin文件描述符,如果暂时没有读/异常事件,则超时。或者,您可以阻止读取并设置计时器(例如Linux上的alarm(2),setitimer())。

(顺便说一句,值得学习如何为你的课程编写流媒体操作符,但这是一个足够大的话题,我不打算在这里深入研究。你还应该考虑使用push_back()来设置输入到你的向量中,而不是使用许多空字符串创建它并对它们进行处理。这样,你不必使用“100”和MAX,但可以简单地让事情在处理输入时“自然地”增长。)

答案 2 :(得分:0)

您应该为用户提供一个转义字符,以使循环退出。


//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++;
 }