是否可以将 getline() 输入分配给另一个单独的字符串?

Is it possible to assign a getline() input to another separate string?

提问人: 提问时间:7/4/2023 最后编辑:General Grievance 更新时间:7/4/2023 访问量:89

问:

我想知道是否有任何可能的方法可以将整个 getline(cin, str) 输入复制/分配给单独的字符串?这是我目前所拥有的:

string str;
// possibly another string strOriginal?
getline(cin, str);

for (i = 0; i < str.size(); ++i) {
    if (isspace(str.at(i))) {
        str.replace(i, 1, "");
    }
}
cout << str;
// cout << strOriginal;

我需要删除字符串内的所有空格,然后使用该新字符串,同时稍后还可以访问原始字符串输入。
前任。如果我要输入一个字符串,例如“Hello everyone”,代码将输出“Helloeveryone”,这是我所需要的,但是,我还需要能够访问原始字符串。
如果有人可以帮助并告诉我这是否可能以及如何做到这一点,那将不胜感激,谢谢!

C++ 字符串 getline

评论

0赞 Sam Varshavchik 7/4/2023
所示的空格删除算法存在致命缺陷:如果字符串在一行中包含两个或多个空格,它将失败。
0赞 7/4/2023
哦,哇,是的,这绝对是正确的......有没有一个简单的方法可以解决这个问题?还是我需要放弃这种方法并以其他方式处理它?
0赞 Chris 7/4/2023
更一般地说:不要在迭代时尝试修改任何内容的集合。
0赞 Tony Delroy 7/4/2023
@Chris:也有例外,例如,在迭代 OR 时擦除 OR 是可以的 - 只需要继续访问/迭代操作返回的迭代器。无论如何,只要索引逻辑跟踪修改,使用索引和重复随机访问(如 OP 所做的那样)进行“迭代”是安全的。std::setstd::maperase
0赞 Sam Varshavchik 7/4/2023
继续阅读你的 C++ 教科书。最终,您将到达解释迭代器和算法的章节,并演示如何执行类似操作,使用 C++ 中的一行代码,使用算法调用和方法调用来删除空格。std::string

答:

2赞 anatolyg 7/4/2023 #1
getline(cin, str);
string strOriginal = str;

我希望这是不言自明的。

1赞 Some programmer dude 7/4/2023 #2

有两种可能的解决方案:第一种是简单地复制原始字符串,然后使用 std::remove_if 和 eraase-remove 习惯用语从副本中删除空格:

// First copy the original string
std::string str_no_space = str;

// Then remove all spaces from the copy
auto new_end = std::remove_if(begin(str_no_space), end(str_no_space),
                              [](char c) { return std::isspace(c); });
str_no_space.erase(new_end, end(str_no_space));

或者,您可以创建一个新字符串并将所有非空格字符复制到其中,请使用 std::copy_if

std::string str_no_spaces;
str_no_space.reserve(str.length());  // Pre-allocate memory, don't set size

// Copy all non-space characters from str into str_no_space
std::copy_if(begin(str), end(str), std::back_inserter(str_no_space),
             [](char c) { return !std::isspace(c); });

// Reallocate to not "waste" memory
str_no_space.shrink_to_fit();

请注意,由于我使用 std::isspace因此将删除所有空格,而不仅仅是单个空格字符。' '

3赞 273K 7/4/2023 #3

有一个简短的解决方案。

#include <algorithm>
#include <iterator>

std::string origin, nospace;
std::getline(cin, origin);
std::remove_copy_if(origin.begin(), origin.end(), std::back_inserter(nospace), ' ');

或者另一个,如果你需要从中使用std::isspace()#include <ccype>

std::remove_copy_if(origin.begin(), origin.end(), std::back_inserter(nospace),
    [](char c) { return std::isspace(static_cast<unsigned char>(c)); });

评论

1赞 Tony Delroy 7/4/2023
它是一个 PITA,但在传递负值时,对于带有 signed 的实现具有未定义的行为。您应该使用 .(一些编译器 - 例如 GCC - 支持 -127..255 值,但它不可移植。[](char c) { return std::isspace(c); }char[](char c) { return std::isspace(static_cast<unsigned char>(c)); }
0赞 Andreas Wenzel 7/4/2023
关于@TonyDelroy的评论,请参阅对另一个问题的回答,了解有关为什么需要演员的更多信息。该答案中有关的信息也适用于 。isdigitisspace
0赞 Jerry Coffin 7/4/2023
有一种稍微简单的方法可以解决这个问题:[](unsigned char c) { return std::isspace(c); }