从 Accelerated C ++ (书),我发现这个代码是相同的程序,但程序本身的处理方式不同,在某些方面使我感到困惑。
下面的代码,很明显,它会在用户包含文件结尾后根据用户输入逐个输出每个单词(通过循环),然后结束程序。
int main()
{
string s;
while (cin >> s)
cout << s << endl;
return 0;
}
与上面的代码不同,这个代码会将每个单词存储在vector
中,然后使用索引i
和j
来检测非空白字符,真正的问题是,我不明白矢量是如何发生的。
vector
中的空白是什么?元素?
首先,我认为程序将继续执行每个字符,因为我认为空白是字符(i
和j
功能是为了),然后,书来,并说它通过每个词,我不知道如何自己测试,我可以看到编译器本身的内部过程如何..
vector<string> split(const string& s)
{
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
// invariant: we have processed characters [original value of i, i)
while (i != s.size())
{
// ignore leading blanks
// invariant: characters in range [original i, current i) are all spaces
while (i != s.size() && isspace(s[i]))
++i;
// find end of next word
string_size j = i;
// invariant: none of the characters in range [original j, current j)is a space
while (j != s.size() && !isspace(s[j]))
j++;
// if we found some nonwhitespace characters
if (i != j) {
// copy from s starting at i and taking j - i chars
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
int main() {
string s;
// read and split each line of input
while (getline(cin, s)) {
vector<string> v = split(s);
// write each word in v
for (vector<string>::size_type i = 0; i != v.size(); ++i)
cout << v[i] << endl;
}
return 0;
}
答案 0 :(得分:3)
您在上面发布的代码确实不将一行文本拆分为单词,基于空格,它会将一行划分为字符。但是,如果代码实际上是可编译的,并且没有遗漏任何必要的大括号({
,}
)。 编辑:实际上,它是否分割单词或单个字符取决于大括号的去向,底线是代码无法编译。
这是一个固定版本的代码,只需移动{{1中的最后一个if
语句,即可拆分每个字,而不是每个字符在它的立即split
块之外:
while
传递给#include <iostream>
#include <vector>
using namespace std;
vector<string> split(const string& s)
{
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
// invariant: we have processed characters [original value of i, i)
while (i != s.size()) {
// ignore leading blanks
// invariant: characters in range [original i, current i) are all spaces
while (i != s.size() && isspace(s[i]))
++i;
// find end of next word
string_size j = i;
// invariant: none of the characters in range [original j, current j)is a space
while (j != s.size() && !isspace(s[j]))
j++;
// if we found some nonwhitespace characters
if (i != j) {
// copy from s starting at i and taking j - i chars
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
int main() {
string s;
// read and split each line of input
while (getline(cin, s)) {
vector<string> v = split(s);
// write each word in v
for (vector<string>::size_type i = 0; i != v.size(); ++i)
cout << v[i] << endl;
}
return 0;
}
的{{1}}会发生什么:
string
)
split
中读取空格
while (i != s.size())
)while (i != s.size() && isspace(s[i]))
)++i
)
string_size j = i
)while (j != s.size() && !isspace(s[j]))
)
j++
)的起点到终点创建一个子字符串,并将该单词添加到if (i != j)
(s.substr(i, j - i)
)。答案 1 :(得分:1)
如果您只是根据空间进行拆分,那么您不需要编写自定义方法。 STL为您提供选择。
std::string line;
std::vector<std::string> strings;
while ( std::getline(std::cin, line))
{
std::istringstream s ( line);
strings.insert(strings.end(),
std::istream_iterator<std::string>(s),
std::istream_iterator<std::string>());
}
// For simplicity sake using lambda.
std::for_each(strings.begin(), strings.end(), [](const std::string& str)
{
std::cout << str << "\n";
});