提问人:Ashkan Arabi 提问时间:8/8/2023 最后编辑:DailyLearnerAshkan Arabi 更新时间:9/5/2023 访问量:51
从 StringStream 中提取字符的 noskipws 导致它不适用于后续字符串提取
noskipws on char extraction from StringStream causes it to not work with subsequent string extractions
问:
让我简单一点。为什么下面的程序写“Thi”而不是“Thisisatest”?我希望它在第一个循环中写入前两个字符,然后写入测试字符串的其余部分,不带空格。
#include <sstream>
#include <iostream>
using namespace std;
int main() {
string test = "This is just a test.";
stringstream ss(test);
char c;
int i = 0;
while (ss >> noskipws >> c) {
int ascii = (int)c;
if (i > 2) { // break after writing 2 characters
break;
}
i++;
cout << c;
}
// continue using the same sstring,
// but with a string instead of a char
// notice that there is no noskipws here
string s;
while(ss >> s) {
cout << s;
}
// program exits with only "Thi" printed
return 0;
}
有趣的是,删除可以解决问题。为什么呢?>> noskipws
答:
0赞
273K
8/8/2023
#1
简化的代码(第一个循环读取 4 个字符并在打印第 4 个字符之前退出):
#include <sstream>
#include <iostream>
using namespace std;
int main() {
string test = " is just a test.";
stringstream ss(test);
ss >> noskipws;
string s;
while(ss >> s) {
cout << s;
}
cout << ss.fail();
}
// Output: 1.
提取到字符串有一个合约:
提取并追加字符,直到出现以下任一情况:
- 文件结束发生在输入序列上;
isspace(c, is.getloc())
对于下一个可用的输入字符 为 true。c
如果未提取任何字符,则在流上设置。
std::ios::failbit
ss >> s
然后,对于上面的每一次阅读,工作都是如此。 在第一个字符上为 true - 未提取任何内容,为空,流设置为失败状态。str.erase()
str.append(1, c)
c
isspace(c, is.getloc())
s
ss
1赞
tbxfreeware
8/8/2023
#2
ss >> s
表示在字符串 S 中读取,并在遇到空格时停止。
我在您的程序中添加了一对额外的输出语句,每个循环的末尾一个。第一个循环结束后,输入流被定位为输入空格作为其下一个字符。
当程序尝试输入字符串 s 时,它会立即遇到空格,并且由于您将流配置为不跳过前导空格,因此它会停止,无法输入字符串 s。该故障会导致流进入失败状态。
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
string test = "This is just a test.";
stringstream ss(test);
char c;
int i = 0;
while (ss >> noskipws >> c) {
int ascii = (int)c;
if (i > 2) { // break after writing 2 characters
break;
}
i++;
cout << c;
}
std::cout << boolalpha
<< "\nAfter first loop: "
<< "\n ss.fail() : " << ss.fail()
<< "\n c : \'" << c << '\''
<< "\n";
// continue using the same sstring,
// but with a string instead of a char
// notice that there is no noskipws here
string s{ "value before ss >> s" };
while (ss >> s) {
cout << s;
}
std::cout << "\nAfter second loop: "
<< "\n ss.fail() : " << ss.fail()
<< "\n s : \"" << s << '\"'
<< '\n';
// program exits with only "Thi" printed
return 0;
}
输出如下:
Thi
After first loop:
ss.fail() : false
c : 's'
After second loop:
ss.fail() : true
s : ""
评论
This
noskipws
ss >> s
failbit
while
noskipws
skipws