我对C ++还是很陌生,所以如果这不是一个好问题,我深表歉意,但是在理解如何使用istream方面我确实需要帮助。
我必须创建一个项目,该项目需要将可能在一行或多个行上的多个输入量传递给一个矢量(这只是该项目的一部分,我想尝试其余的输入我自己的),例如,如果我要输入...
>> aaa bb
>> ccccc
>> ddd fff eeeee
使用“ aaa”,“ bb”,“ ccccc”,“ ddd”,“ fff”,“ eeeee”作为字符串的向量
输入可以是char或字符串,并且在按下回车键时程序会停止要求输入。
我知道getline()获得了一行输入,我可能可以使用while循环尝试获取诸如...的输入(如果我错了,请纠正我)
while(!string.empty())
getline(cin, string);
但是,我并没有真正理解istream,并且我的课程没有遍历指针也无济于事,所以我不知道如何使用istream&或string&将其传递给向量。在项目描述中,它说不使用stringstream,而是使用getline(istream&,string&)中的功能。任何人都可以对如何使用getline(istream&,string&)创建函数,然后如何在主函数中使用它进行详细的解释吗?
有什么帮助!
答案 0 :(得分:1)
您可以输入第一列的值,然后基于该值调用函数:
void Process_Value_1(std::istream& input, std::string& value);
void Process_Value_2(std::istream& input, std::string& value);
int main()
{
// ...
std::string first_value;
while (input_file >> first_value)
{
if (first_value == "aaa")
{
Process_Value_1(input_file, first_value);
}
else if (first_value = "ccc")
{
Process_Value_2(input_file, first_value);
}
//...
}
return 0;
}
一个示例函数可以是:
void Process_Value_1(std::istream& input, std::string& value)
{
std::string b;
input >> b;
std::cout << value << "\t" << b << endl;
input.ignore(1000, '\n'); // Ignore until newline.
}
还有其他方法可以执行此过程,例如使用函数指针表和std::map
。
答案 1 :(得分:1)
您已经走对了路;完全是这样,您必须用一些虚拟对象预填充字符串才能完全进入while循环。更优雅:
std::string line;
do
{
std::getline(std::cin, line);
}
while(!line.empty());
如果用户输入一个空行,这应该已经可以逐行(但是可能在一行上有多个单词!)并完成技巧的读取(请注意,空格和换行符不会被这样识别!)
但是,如果流中有任何错误,您将陷入无限循环中,一次又一次地处理先前的输入。因此最好也检查流状态:
if(!std::getline(std::cin, line))
{
// this is some sample error handling - do whatever you consider appropriate...
std::cerr << "error reading from console" << std::endl;
return -1;
}
由于一行上可能有多个单词,因此您必须将它们分开。 有多种方法,一种很简单的方法是使用 < / p> std::istringstream
–您会发现它与您可能习惯使用std::cin
的样子相似:
std::istringstream s(line);
std::string word;
while(s >> word)
{
// append to vector...
}
请注意,使用operator>>
会忽略前导空格,并在第一个尾随空格(或流的末尾,如果到达)之后停止,因此您不必显式处理。 / s>
好的,您不允许使用std::stringstream
(好吧,我使用的是std::
i stringstream
,但我想这个小区别并没有计数,是吗?)。更改有一点点,它变得更加复杂,另一方面,我们可以自己决定什么算作单词,什么算作分隔符...我们可以将标点符号视为分隔符,就像空格一样,但是允许数字成为单词的一部分,所以我们接受e。 G。 ab.7c d
为"ab", "7c", "d"
:
auto begin = line.begin();
auto end = begin;
while(end != line.end()) // iterate over each character
{
if(std::isalnum(static_cast<unsigned char>(*end)))
{
// we are inside a word; don't touch begin to remember where
// the word started
++end;
}
else
{
// non-alpha-numeric character!
if(end != begin)
{
// we discovered a word already
// (i. e. we did not move begin together with end)
words.emplace_back(begin, end);
// ('words' being your std::vector<std::string> to place the input into)
}
++end;
begin = end; // skip whatever we had already
}
}
// corner case: a line might end with a word NOT followed by whitespace
// this isn't covered within the loop, so we need to add another check:
if(end != begin)
{
words.emplace_back(begin, end);
}
对于什么是分隔符和什么算作单词(例如std::isalpha(...) || *end == '_'
,以便将下划线检测为单词的一部分,而数字不是),适应不同的解释应该不太困难。您可能会发现很多helper functions有用...