标题:关于 std::ends
只看楼主
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
结帖率:91.67%
已结贴  问题点数:20 回复次数:8 
关于 std::ends
连续好几天看你们在讨论 std::ends,似乎你们都明白它是输出'\0',后面你们的争论我就看不懂了,也没细看。

在上世纪C++98之前,<strstream>中有个std::ostrstream。现在已经被<sstream>中的std::ostringstream给替换了。
std::ostrstream s;
s << "abc";
char* p = s.str(); // 冻结缓冲区(因为返回的是一个指针),并返回 'a','b','c'(注意尾部没有'\0') 这样一个序列的起始地址.
// std::cout << p; 不能这么做,因为 p 不是指向以null结尾的字符串(可以这么做 std::cout.write(s.str(), s.pcount()))
// 正确的做法是解冻后,尾部加个'\0',让它成为以null结尾的字符串
s.freeze(false);
s << ends;
std::cout << s.str(); // 这时是正确的,返回序列 'a','b','c','\0'
s.freeze(false); // 别忘了解冻,否则会内存泄漏
简而言之,std::ostrstream::str() 并不主动在缓冲区添加'\0',所以要想它返回一个null结尾的字符串,用户得自己向缓冲区输出std::ends
程序代码:
#include <iostream>
#include <strstream>
int main()
{
    std::ostrstream s; // 动态缓冲区
    s << “abc" << std::ends;
    std::cout << s.str() << '\n';
    s.freeze(false);
}

C++98时新的 std::ostringstream 就没这些破事,不需要冻结缓冲区,也不需要std::ends
程序代码:
#include <sstream>
#include <iostream>
int main()
{
    std::ostringstream s;
    s << "abc"; // 不需要,也不应该添加 std::ends
    std::cout << s.str() << '\n';
    // 不需要冻结缓冲区,因为 std::ostringstream::str() 返回的是一个std::string类型的缓冲区副本
}

-------
我又看了一下你们的讨论,似乎不是在纠结 std::ends,而是 一个说putchar('\0')是可以的,一个说putchar('\0')是没意义的。
收到的鲜花
  • 叶纤2020-03-18 12:33 送鲜花  20朵   附言:光明使者
搜索更多相关主题的帖子: 缓冲区 std str ends 返回 
2020-03-18 09:43
纯蓝之刃
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:76
帖 子:554
专家分:3690
注 册:2019-7-29
得分:7 
我只是静静的看着

一沙一世界,一花一天堂。无限掌中置,刹那成永恒。
2020-03-18 10:22
lin5161678
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:45
帖 子:1136
专家分:3729
注 册:2011-12-3
得分:7 
ends 本身没什么值得讨论了
我都贴截图出来了
一个putchar('\0')
可能没输出 可能输出空格 甚至可能输出a

我只是在解释 为什么cout<<ends能编译运行但还是错误 这个道理
我发现很多新手都会有 能编译运行就是对的 这样的想法
这需要纠正 尤其是C/C++ 有很多未定义行为
这些东西能编译运行 但还是错误


https://zh.
2020-03-18 11:02
lin5161678
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:45
帖 子:1136
专家分:3729
注 册:2011-12-3
得分:0 
从你查到的资料来看
ends的确如我所说 根本不是给cout使用的
是给一个废弃类型设计的
现在只是一个历史痕迹 没实际应用价值
使用cout << ends 这样的做法只是自找麻烦
写给新手更是会误人子弟

https://zh.
2020-03-18 11:04
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:7 
程序代码:
看看人家的举例多有信服力度,
你非要拿着未初始的变量和我举例,我怎么看都不明白呀就知道楼上认为ends不是给cout用的,但是和cout n没关系啊
还好我昨天科普点I/O的知识楼主的代码还是可以看懂的
程序代码:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    int n;
    cout << n;    
    return 0;
}



把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-03-18 12:14
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:0 
回复 楼主 rjsp
那std :: basic_ostream。和cout,cerr是什么关系啊,
算了,我有时间的时候认真看看io的知识点,估计就能找到了

[此贴子已经被作者于2020-3-18 12:41编辑过]


把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-03-18 12:24
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
以下是引用叶纤在2020-3-18 12:24:29的发言:

那std :: basic_ostream。和cout,cerr是什么关系啊,
算了,我有时间的时候认真看看io的知识点,估计就能找到了
cout、clog、cerr 都是 std::basic_ostream<char> 类型的变量。

cout 对应于C语言的stdout带缓存
clog 对应于C语言的stderr带缓存
cerr 对应于C语言的stderr不带缓存
2020-03-18 12:54
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:0 
我把每一个代码都当成解密游戏,等我把这个谜题解开了再答谢lin5161678大大,r版主的代码就是高级boss怎么都解不开,就比如
程序代码:
std::string foo( const std::string& s, size_t offset )
{
    if( offset < s.size() )
        return string(s, offset);
    return string();
}我把我教材里关于string的知识点都看了,接触了string—view,然后也接触了如签名里一大堆的函数,一时接触的太多怕忘就全写到了签名里,但是就是解不开为什么可以直接返回参数结果没有变,然后就把指针的知识点也一同看了,突然感觉自己等级太低,搞不定boss的代码,自己要不停的刷级才能搞定一条,还好这里可以直接和boss对话,,,,解boss的代码也不是很困难了

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-03-18 13:24
ljj2510
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2021-12-2
得分:0 
2022-01-11 00:06



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-500401-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.249830 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved