Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;不';我不能像我想的那样工作_C++_Istream - Fatal编程技术网

C++ C++;不';我不能像我想的那样工作

C++ C++;不';我不能像我想的那样工作,c++,istream,C++,Istream,unget的工作方式和我想象的不一样。。。让我解释一下。正如我所想,unget获取流中提取的最后一个字符,并将其放回流中(并准备再次提取)。在内部,它减少了流缓冲区中的指针(创建哨兵和其他东西) 但是,当我一个接一个地使用两个unget()时,它的行为会变得非常奇怪。如果你写一些类似于hello的东西,你观察到的问题一点也不奇怪。首先,请注意,底层流缓冲区可能支持取消设置字符,也可能不支持取消设置字符。通常,至少支持一个字符的回拨。这是否真实以及是否支持更多字符完全取决于流缓冲区 测试程序中发生

unget的工作方式和我想象的不一样。。。让我解释一下。正如我所想,unget获取流中提取的最后一个字符,并将其放回流中(并准备再次提取)。在内部,它减少了流缓冲区中的指针(创建哨兵和其他东西)


但是,当我一个接一个地使用两个unget()时,它的行为会变得非常奇怪。如果你写一些类似于
hello的东西,你观察到的问题一点也不奇怪。首先,请注意,底层流缓冲区可能支持取消设置字符,也可能不支持取消设置字符。通常,至少支持一个字符的回拨。这是否真实以及是否支持更多字符完全取决于流缓冲区

测试程序中发生的情况很简单,第二次
unget()
失败,流进入失败状态(即设置了
std::ios\u base::failbit
),另一次读取某个内容的尝试失败。失败的读取使原始缓冲区保持不变,并且由于未对其进行测试(它应该进行测试),因此看起来好像相同的字符串被读取了两次

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

std::ios_base::sync_with_stdio(false);

这将提高性能,并使更多角色获得成功的可能性。仍然无法保证您可以将多个字符(甚至仅一个字符)放回原处。如果你真的需要回放字符,你应该考虑使用一个过滤流缓冲器,它支持你需要的尽可能多的字符回退。一般来说,标记化输入不需要任何字符的回拨,这是只有一般支持的基本原因:因为回拨支持不好,所以最好使用适当的标记化,以减少改进回拨的需要。有点像循环论证。由于您可以创建自己的流缓冲区,因此它实际上并不有害。

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

测试程序中发生的情况很简单,第二次
unget()
失败,流进入失败状态(即设置了
std::ios\u base::failbit
),另一次读取某个内容的尝试失败。失败的读取使原始缓冲区保持不变,并且由于未对其进行测试(它应该进行测试),因此看起来好像相同的字符串被读取了两次

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

std::ios_base::sync_with_stdio(false);

这将提高性能,并使更多角色获得成功的可能性。仍然无法保证您可以将多个字符(甚至仅一个字符)放回原处。如果你真的需要回放字符,你应该考虑使用一个过滤流缓冲器,它支持你需要的尽可能多的字符回退。一般来说,标记化输入不需要任何字符的回拨,这是只有一般支持的基本原因:因为回拨支持不好,所以最好使用适当的标记化,以减少改进回拨的需要。有点像循环论证。由于您总是可以创建自己的流缓冲区,因此它实际上并不有害。

这种行为的实际原因与前面的答案中解释的流的故障位有关。我可以提供一个变通代码,帮助您实现所需的结果

#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
// compile using g++ -std=c++11 -lboost_iostreams

#define MAX_CHARS 256
using namespace std;

int main(){

    boost::iostreams::filtering_istream cinn(std::cin,0,1);
    char cadena[MAX_CHARS];

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

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

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

    cout << "Your phrase with 2 ungets done..." << cadena;
    return 0;
}
#包括
#包括
//使用g++-std=c++11-lboost\u iostreams编译
#定义最大字符数256
使用名称空间std;
int main(){
boost::iostreams::filtering_istream cinn(std::cin,0,1);
char cadena[MAX_CHARS];

cout此行为的实际原因与前面的答案中解释的流的故障位有关。我可以提供一个变通代码,帮助您实现所需的结果

#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
// compile using g++ -std=c++11 -lboost_iostreams

#define MAX_CHARS 256
using namespace std;

int main(){

    boost::iostreams::filtering_istream cinn(std::cin,0,1);
    char cadena[MAX_CHARS];

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

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

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

    cout << "Your phrase with 2 ungets done..." << cadena;
    return 0;
}
#包括
#包括
//使用g++-std=c++11-lboost\u iostreams编译
#定义最大字符数256
使用名称空间std;
int main(){
boost::iostreams::filtering_istream cinn(std::cin,0,1);
char cadena[MAX_CHARS];

难道“我以为unget每次被调用时都与最后一个字符一起工作”-不,只有一次。那么它是如何工作的?(感谢黑暗猎鹰在我的帖子中正确地放置了<)@n、 m:流缓冲区接口中没有任何东西可以阻止尽可能多的放回字符…也没有任何东西可以保证你甚至可以放回一个字符!这完全取决于流缓冲区。“我认为unget每次调用时都会与最后一个字符一起工作”-不,只有一次。那么它是如何工作的?(感谢黑暗猎鹰在我的帖子中正确地添加了<)@ N.M.:流缓冲区中的任何东西都不阻止你想要的多个回放字符…而且没有任何东西保证你甚至能返回一个字符,完全取决于流缓冲器。所以它完全依赖于我正在使用的CIN实现?难道没有为C++中的流解开ANSI函数吗?我感到困惑。什么是stdin?为什么它与cin同步?谢谢你的回答。@Carrascado:
std::istre