最近的一个项目有点问题。这里的目标是能够输入几行文本,其中包含以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标记,用户输入仍然可以继续。有什么理由可能会发生这种情况?
答案 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++;
}