std::string是否只能包含Ascii字符?

5

std::string是否应该在所有平台和标准编译器上保存Ascii编码字符集?

换句话说,如果我这样做,我的C++程序是否可以确保获取一组Ascii字符:

std::string input;
std::getline(std::cin, input);

编辑:

更准确地说,我想确保如果用户输入"a0",我将获得一个包含两个元素的std::string。第一个元素是97,第二个元素是48


2
绝对没有保证。UTF-8是一种非常流行的字符编码,如果在这样的系统上键入“á0”,则您的字符串将包含三个元素。 - Mark Ransom
@MarkRansom 我明白了。我会发另一个问题,询问如何强制或确保输入的是 ASCII 字符串。谢谢。 - Humam Helfawi
我有一个变量std::string xml。编译器或STL是否强制要求其中只有XML字符串?- 不是的。类型是`char'而不是"XML"或"Unicode"。不要混淆类型、格式或编码。但是其中确实有一个有效的问题:“我如何控制标准IO编码?” - Fozi
@Fozi 是的,你说得对。我已经在 http://stackoverflow.com/questions/37953843/how-can-force-the-user-os-to-input-an-ascii-string 上提出了这个问题。 - Humam Helfawi
@HumamHelfawi:我认为正确的做法是,验证输入是否仅包含ASCII字符,如果这是您的前提条件,那将是很容易实现的。如果输入不符合条件,应该显示明确的错误信息。我不认为可以从Unicode字符“转回”表示用户按键的ASCII字符,那可能会非常困难。如果您真正想知道如何重新配置终端以使其有不同的行为,我认为那也会很困难,并且将依赖于平台。 - Chris Beck
3个回答

10
注意,std::string 并不是存储"字符",它存储的是字节 这些字节可以通过 ASCII、EDBCIC 或 Unicode 编码形成人类可读的字符串。它们也可以是二进制编码存储计算机可读信息(例如 JPEG 图像)。它们甚至可以是外星人给你关于如何在 Stack Overflow 上三周不被踩的指引。或者是完全随机的白噪声。
作为程序员,你需要让你的程序了解它正在读取的数据实际上意味着什么,以及它如何被编码。这将是你任务的一部分。
(遗憾的是,在现在看来,char 的命名可能会误导人。)

1
现在我很高兴,因为没有被人踩。至少,我可能会在某天找到这些指南。 - Humam Helfawi
@HumamHelfawi:假设你能编写一个程序来解码那些准则 ;) - Lightness Races in Orbit
你是说即使char是有符号类型,它也是一个byte吗? - R Sahu
@RSahu:完全没问题。 - Lightness Races in Orbit
char缩写自"character",这完全是误导(因此有了这个问题);byte字面上就是该类型的含义,尽管确实有一个带有自己含义的上位比特变体。但是咳咳,我们就忽略带符号的chars吧 ;) 让我们假设signed char(以及默认带符号char平台上的char)是一个CHAR_BIT位整数,然后就完成了 ;) 但从不是"字符"。 - Lightness Races in Orbit
显示剩余7条评论

3
不,没有保证
std::string input;
std::getline(std::cin, input);

只会返回ASCII字符。 char 可以容纳的值的范围不仅限于ASCII字符。

如果您的平台使用与ASCII不同的编码,则显然会得到不同的字符集。

即使您的平台使用ASCII编码,如果平台上的char是无符号类型,则它也可以非常容易地容纳扩展的ASCII字符


谢谢。如果我想将输入视为Ascii,我该怎么办?如果您不介意,只提供一个链接就可以了。(由于存在大量错误和不成熟的上下文,我害怕自己查找) - Humam Helfawi
@HumamHelfawi,您是在询问如何防止非ASCII字符被读入“input”吗? - R Sahu
更准确地说,我想确保如果用户输入"a0",我将获得一个包含两个元素的字符串。第一个元素是97,第二个元素是48。 - Humam Helfawi
4
std::string 可以保存任何内容,std::cin 可以读取任何内容,与所用的平台编码、ASCII 或扩展 ASCII 没有任何关系。如果尝试使用 dd 的结果或 cat someimage.jpg 进行输入,就会发现这一点。正确的答案是:std::string 完全没有编码概念。std::cin 也是如此。 - Lightness Races in Orbit
无论 char 是有符号还是无符号,它都可以容纳扩展字符集,而不仅仅是 ASCII。 - Mark Ransom
显示剩余3条评论

3
换句话说,如果我这样做,我的C++程序能确保得到一组Ascii字符吗?
不行。 实际上,std::stringstd::basic_string<> 的一个特化版本,就像
using std::string std::basic_string<char>;:
template< 
    class CharT, 
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT>
> class basic_string;

并且可以容纳使用Traits定义的任何字符类型。

简而言之,std::string可以包含ASCII字符编码,以及EBCDIC或其他任何编码。但是在使用时应该透明无感知。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接