将字符串拆分为字</string>的向量<string>

时间:2011-12-08 01:56:53

标签: c++ string vector element

Accelerated C ++ (书),我发现这个代码是相同的程序,但程序本身的处理方式不同,在某些方面使我感到困惑。

下面的代码,很明显,它会在用户包含文件结尾后根据用户输入逐个输出每个单词(通过循环),然后结束程序。

int main()
{
    string s;
    while (cin >> s)
        cout << s << endl;
    return  0;
}

与上面的代码不同,这个代码会将每个单词存储在vector中,然后使用索引ij来检测非空白字符,真正的问题是,我不明白矢量是如何发生的。

vector中的空白是什么?元素?

首先,我认为程序将继续执行每个字符,因为我认为空白是字符ij功能是为了),然后,书来,并说它通过每个,我不知道如何自己测试,我可以看到编译器本身的内部过程如何..

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

2 个答案:

答案 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";
        });