简体   繁体   English

C ++-查找功能无法在子字符串上执行

[英]C++ - find function does not work executed on substring

I do have got a problem with an algorithm, which I want to use to split command line into several substrings. 我的算法确实有问题,我想使用该算法将命令行拆分为几个子字符串。 Eg the string "Hello World -n filename" should be sliced into "Hello" "World" and "-n filename" . 例如,字符串"Hello World -n filename"应被切片为"Hello" "World""-n filename"

Here is my whole code example: 这是我的整个代码示例:

string hello = "Hello World -n filename";
uint64_t startIndex = 0;
uint64_t endIndex = hello.length() - 1;

while(startIndex < endIndex) {
    uint64_t nextWhiteSpaceIndex;
    string value;

    if(hello.at(startIndex) != '-') {

        nextWhiteSpaceIndex = hello.substr(startIndex).find(" ");
        value = hello.substr(startIndex, nextWhiteSpaceIndex);
        cout << value << endl;

    } else {

        nextWhiteSpaceIndex = hello.substr(hello.substr(startIndex).find(" ")).find(" ");
        value = hello.substr(startIndex, nextWhiteSpaceIndex);
        cout << value << endl;

    }
    startIndex = nextWhiteSpaceIndex + 1;
}

And I do have problems with this command: 我确实对此命令有疑问:

nextWhiteSpaceIndex = hello.substr(startIndex).find(" ");

This is placed within the while-loop and it seems like the... 这被放置在while循环中,似乎...

.substr(startIndex)

... part is completely ignored. ...部分被完全忽略。 The first loop run works fine, but during the second/following the nextWhiteSpaceIndex does not get the right next index assigned. 第一个循环运行正常,但是在第二个循环/之后,nextWhiteSpaceIndex不能正确分配下一个索引。 It always prints "Hello" "World" "World" "World" "World" and continues to print "World" . 它始终打印"Hello" "World" "World" "World" "World"并继续打印"World"

Do you guys have a hint, why this does not work? 你们有一个提示,为什么这不起作用? I could not find an appropriate explanation during my research through the web. 我在通过网络进行研究时找不到合适的解释。

Can't you do something like 你不能做类似的事情

#include <sstream>
#include <stdio>
#include <vector>

using namespace std;

int main ()
{
    string hello = "Hello World -n filename";

    stringstream ss (hello);
    vector<string> v;
    string s, t;

    while (ss >> s)
    {
        if (s[0] == '-')
        {   
            ss >> t;
            v.push_back (s + " " + t); 
        }   
        else
            v.push_back (s);
    }

    for (auto i : v)
        clog << i << endl;

    return 0;
}

produces 产生

$ ./a.out
Hello
World
-n filename

If you output the value for nextWhiteSpaceIndex you will always see: 5, 5, 5, 5... It's an index relative to startIndex , so simply changing the last line into startIndex += nextWhiteSpaceIndex + 1; 如果输出nextWhiteSpaceIndex的值,您将始终看到: nextWhiteSpaceIndex ...这是相对于startIndex的索引,因此只需将最后一行更改为startIndex += nextWhiteSpaceIndex + 1; would probably quickfix the issue. 可能会解决这个问题。

(Aren't you taking too many substrings? std::string::find can take the search start index as argument, so you can perform the whole search on always the same buffer.) (您是否接受了太多的子字符串? std::string::find可以将搜索开始索引作为参数,因此您可以在始终相同的缓冲区上执行整个搜索。)

hello is never changed, yet you're using find on only part of it ( substr ), and then calling substr(startIndex) on the whole string ( hello ) over and over again. hello永远不会改变,但是您只在它的一部分( substr )上使用find ,然后一遍又一遍地在整个字符串( hello )上调用substr(startIndex)

  1. "Hello World -n filename".find(" ") -> 5 "Hello World -n filename".find(" ") -> 5
  2. "World -n filename".find(" ") -> 5 again ("World" is the same length as "Hello") 再次"World -n filename".find(" ") -> 5(“ World”与“ Hello”的长度相同)
  3. "World -n filename".find(" ") -> 5 "World -n filename".find(" ") -> 5

You could use std::string::find 's second argument ( size_type pos ) to specify the start offset where to start the search and create fewer temporary strings: 您可以使用std::string::find的第二个参数( size_type pos )指定开始搜索的起始偏移量,并创建更少的临时字符串:

#include <iostream>

using namespace std;

int main() {
  const string hello = "Hello World -n filename";

  size_t startIndex = 0, pos = 0;
  bool eat = true;

  while(true) {
    pos = hello.find('\x20', pos);

    if(pos == string::npos) {
      cout << hello.substr(startIndex) << endl;
      break;
    }
    else if(eat && hello[startIndex] == '-') {
      eat = false;
      ++pos;
      continue;
    }

    cout << hello.substr(startIndex, pos - startIndex) << endl;

    startIndex = ++pos;
    eat = true;
  }

  return 0;
}

Output: 输出:

$ c++ main.cpp && ./a.out
Hello
World
-n filename

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM