将字符串拆分为vector< string>的话 [英] Splitting string into a vector<string> of words

查看:215
本文介绍了将字符串拆分为vector< string>的话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

加速的C ++ (书)中,我发现此代码是相同的程序,但是在程序本身中所处理的是不同的,并使我感到困惑。

From Accelerated C++(book), I found this code which is identical program, but the processed in program itself is different, and confused me on some part.

下面的代码显然可以在用户包含文件末尾之后根据用户输入逐个输出每个单词,然后结束程序。

The code below, well, obviously it will output each word one-by-one(by loops) based on user input after the user included end-of-file, then, end the program.

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

与上面的代码不同,此代码将每个单词存储在 vector ,然后使用索引 i j 来检测非空白字符,真正的问题是,我不理解向量是如何发生的。

Unlike code above, this one will store each word in a vector, then use index i and j to detect the non-whitespace character, and the real question is, I don't understand how it happens with the vector.

向量

起初,我认为程序会通过每个字符进行,因为我认为空白是字符(这是 i j 的功能),然后,这本书就说要对每个 word ,我自己也不知道如何测试它,就像我看到编译器本身的内部过程一样。

At first, I thought the program will proceed through each character, because I thought the whitespace is character(which i and j functionality is for), then, the book come and said it proceed through each word, I don't know how to test this myself, like I can see how the inner process in the compiler itself..

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


推荐答案

您上面发布的代码确实将一行文本分割为多个单词,根据空格将其替换为字符。但是,如果代码实际上是可编译的,并且没有遗漏任何必要的花括号( {} )。 编辑:实际上,是否拆分单词或单个字符取决于大括号的位置,最重要的是代码不会编译。

The code you posted above does not split a line of text into words, based on whitespace, it instead splits a line into characters. However, that's if the code was actually compilable and not missing any necessary braces ({, }). Actually whether it splits words or individual characters depends on where the braces go, bottom line is that the code doesn't compile.

这是一个固定版本的代码,它通过简单地移动最后一个 if word 而不是每个 character >在紧接块之外的 中的语句:

Here is a fixed version of the code that splits each word, rather than each character, by simply moving the last if statement in split outside of it's immediate while block:

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

字符串传递给 split 的是:


  • 同时字符串中的字符仍然是 while(i!= s.size())

    • 虽然我们正在从字符串<$中读取空格c $ c> while(i!= s.size()&& isspace(s [i]))

      • 增加计数器直到我们找到单词的开头( ++ i

      • While still characters in the string (while (i != s.size()))
        • While we're reading a space from the string while (i != s.size() && isspace(s[i]))
          • Increment the counter until we get to the start of a word (++i)

          • 增加指示单词结尾的计数器( j ++

          • Increment the counter indicating the end of the word (j++)

          • 从单词的起点到终点创建一个子字符串( s.substr(i,j-i)),并将该单词添加到 vector ret。 push_back(..))。

          • Create a sub-string from the start point to the end point of the word (s.substr(i, j - i)), and add that word to the vector (ret.push_back(..)).

          这篇关于将字符串拆分为vector&lt; string&gt;的话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆