如何获取一个字符串,在字符的最后一次出现之前。

3

编辑1

我忘记说这个字符串必须从 cin 中获取

我有一个字符串,如 "Hi; my;; name is Andrea; and I like C++"。 我想创建一个用该字符串初始化的 stringstream,并获取最后一个 ; 之前的所有内容。

这是我尝试过的:

    string ex("Hi; my;; name is Andrea;; and I like C++"), text, final_text;
    stringstream loop_stream(ex);
    int findComma = loop_stream.str().find(';');
    do {
        getline(loop_stream, text, ';');
        loop_stream.ignore(1);
        final_text += text;
        loop_stream << loop_stream.rdbuf();
        findComma = loop_stream.str().find(';');
        while (findComma == 1) {
            loop_stream.ignore(1);
        }
        findComma = loop_stream.str().find(';');
    }
    while (findComma != string::npos);

    cout << "-" << final_text << "-" << endl;

但它根本不起作用... 我想要的输出结果是:

-Hi; my;; name is Andrea-

为什么要做那么复杂的事情,而不是使用string::rfind搜索最后一个';',然后使用string::substr获取期望的子字符串呢? - bruno
我认为OP不知道你可以从字符串的末尾开始向后搜索。 - PaulMcKenzie
如果你创建一个函数来解决问题,那么字符串的来源并不重要。也许这就是为什么你的代码比它应该的更复杂的原因--你试图将输入例程与字符串操作混合编写。 - PaulMcKenzie
4个回答

4

这里是使用 find_last_of 的另一种解决方案:

#include <string>
#include <iostream>

int main()
{
   std:: string test = "Hi; my;; name is Andrea; and I like C++";
   auto pos = test.find_last_of(";");
   if ( pos != std::string::npos)
      std::cout << test.substr(0, pos);
}

输出:

Hi; my;; name is Andrea

使用函数:

#include <string>
#include <iostream>

std::string parseString(const std::string& s)
{
   auto pos = s.find_last_of(";");
   if ( pos != std::string::npos)
      return s.substr(0, pos);
   return s;
} 

int main()
{
   std::cin >> test;  // assume the string will be inputed
   std::cout << parseString(test);
}

谢谢,但我刚意识到我写的问题与我想要表达的不同,我需要从cin中获取字符串。 - John Bardeen
不应该关心字符串来自哪里。将我发布的代码转换为一个返回std::string的函数,并使用输入字符串调用该函数。 - PaulMcKenzie
如果用户想要开始新的一行,这个是否也适用? - John Bardeen
1
编程中有一个设计原则叫做关注点分离。无论输入字符串来自何处或如何解析,函数只做一件事情——获取包含所有分号的字符串,并将结果返回给调用者。它不关心接收到的字符串是在何时、何地或如何生成的。正如我在主要部分中的评论所指出的那样,这可能是您原始解决方案过于复杂的原因。 - PaulMcKenzie

1

你觉得使用stringstream不够简单,那么有没有更简单的方法呢:

string ex("Hi; my;; name is Andrea;; and I like C++");
size_t pos = ex.rfind(';'); // find last semicolon
string final_text = ex.substr(0, pos);

谢谢,但我刚意识到我写的问题与我想要表达的不同,我需要从cin中获取字符串。 - John Bardeen
@JohnBardeen:好的,那么使用std::getline()cin中获取整个字符串,然后应用我的解决方案。 - John Zwinck
请纠正我,但如果字符串包含换行符,我无法执行此操作。 - John Bardeen
你可以反复调用getline()(我最喜欢的方法),或者使用最大可能输入长度调用cin.read()到单个缓冲区中(在这种情况下,您必须预先知道最大长度)。 - John Zwinck
我所询问的一切都是由我的教授布置的项目所需要的... 用户应该能够在编写命令时编辑整个命令... - John Bardeen

0
你可以使用 istreambuf_iteratoristream 中构造一个 string(例如 std::cin)。之后,只需使用其他答案中的一种来提取所需内容即可:
#include<iostream>
#include<iterator>
#include<sstream>

int main(){
    std::istringstream loop_stream("Hi; my;; name is Andrea;; and I like C++");

    // read the stream until it's depleted and put it in a string:
    std::string all_stream(std::istreambuf_iterator<char>(loop_stream),
                           std::istreambuf_iterator<char>{});

    // use any of the other answers, like this:

    std::string final_text;
    if(auto pos = all_stream.find_last_of(";"); pos != all_stream.npos) {
        final_text = all_stream.substr(0, pos);
    }

    std::cout << '-' << final_text << "-\n";
}

输出:

-Hi; my;; name is Andrea-

-2
你陷入了一个重复循环中,请检查循环的条件。我认为findComma存在问题,它的值没有更新。

3
这是一条评论,而非回答。 - Ted Lyngmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接