gpt4 book ai didi

c++ - C++ 中的 istream::unget() 没有像我想的那样工作

转载 作者:太空宇宙 更新时间:2023-11-03 10:29:53 26 4
gpt4 key购买 nike

unget 并没有像我想象的那样工作……让我自己解释一下。正如我所想,unget 获取流中提取的最后一个字符,并将其放回流中(并准备好再次提取)。在内部,它正在减少流缓冲区中的指针(创建哨兵和所有这些东西)。

但是,当我一个接一个地使用两个 unget() 时,它的行为变得非常奇怪。如果写类似 hello<bye 的东西,我使用 <作为定界符,如果我使用 getline 然后再使用两个 ungets,它会返回 hello,没有 o<bye" .这是我的代码:

#include <iostream>
#define MAX_CHARS 256

using namespace std;

int main(){

char cadena[MAX_CHARS];

cout << "Write something: ";
cin.getline(cadena, MAX_CHARS, '<');

cout << endl << "Your first word delimited by < is: " << cadena << endl;

cin.unget(); //Delimiter (removed by getline) is put back in the stream
cin.unget(); //!?
cin >> cadena;

cout << "Your phrase with 2 ungets done..." << cadena;
return 0;
}

试试 bye<hello , 然后 cadena 得到 bye而不是 e<hello我认为 unget 每次调用时都与最后一个字符一起使用,这到底是怎么回事?

最佳答案

您观察到的问题一点也不奇怪。首先,请注意底层流缓冲区可能支持也可能不支持 ungetting 字符。通常,至少支持一个 putback 字符。这是否真的如此以及是否支持更多字符完全取决于流缓冲区。

在您的测试程序中发生的只是第二个 unget() 失败,流进入失败状态(即,std::ios_base::failbit 是set) 和另一个读取内容的尝试失败了。失败的读取保留原始缓冲区不变,并且由于它没有经过测试(应该如此),看起来同一个字符串被读取了两次。

std::cin 可能支持只放一个字符的根本原因是它默认与stdin 同步。结果,std::cin 不做任何缓冲(导致它在这方面也相当慢)。如果不与 stdin 同步,您很有可能获得更好的结果:

std::ios_base::sync_with_stdio(false);

这将提高性能和放置更多角色成功的可能性。仍然不能保证您可以放回多个字符(甚至只有一个字符)。如果你真的需要回放字符,你应该考虑使用一个过滤流缓冲区,它支持你需要的尽可能多的字符回放。通常,标记化输入不需要 putback 的任何字符,这是只有平庸支持的基本原因:由于 putback 支持很差,您最好使用适当的标记化来减少改进 putback 的需要。有点循环论证。不过,由于您始终可以创建自己的流缓冲区,所以这并不是真正有害的。

关于c++ - C++ 中的 istream::unget() 没有像我想的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20056620/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com