Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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++ 您如何处理签名字符->;标准库的int问题?_C++_C_Character Encoding_Special Characters - Fatal编程技术网

C++ 您如何处理签名字符->;标准库的int问题?

C++ 您如何处理签名字符->;标准库的int问题?,c++,c,character-encoding,special-characters,C++,C,Character Encoding,Special Characters,这是我工作中一个长期存在的问题,我意识到我仍然没有一个很好的解决方案 C天真地定义了int的所有字符测试函数: int isspace(int ch); 但是字符通常是有符号的,一个完整的字符通常不能放在int中,也不能放在用于字符串的任何单个存储单元中 这些函数已经成为当前C++函数和方法的逻辑模板,为当前标准库设置了阶段。事实上,他们仍然受到支持 因此,如果您将isspace(*pchar)交给用户,最终可能会出现符号扩展问题。根据我的经验,它们很难被看到,也很难被防范 类似地,由于iss

这是我工作中一个长期存在的问题,我意识到我仍然没有一个很好的解决方案

C天真地定义了int的所有字符测试函数:

int isspace(int ch);
但是字符通常是有符号的,一个完整的字符通常不能放在int中,也不能放在用于字符串的任何单个存储单元中

这些函数已经成为当前C++函数和方法的逻辑模板,为当前标准库设置了阶段。事实上,他们仍然受到支持

因此,如果您将isspace(*pchar)交给用户,最终可能会出现符号扩展问题。根据我的经验,它们很难被看到,也很难被防范

类似地,由于isspace()及其类似的函数都取整数,而且由于字符的实际宽度通常是未知的,不需要进行字符串分析,这意味着任何现代字符库基本上都不应该在char或wchar_t上运行,而只需要指针/迭代器,因为只有通过分析字符流,您才能知道其中有多少组成了一个逻辑字符,所以对于如何最好地处理这些问题,我有点不知所措

我一直在期待一个真正强大的库,它基于对任何字符的大小因子进行抽象,并且只处理字符串(提供isspace等内容),但要么我错过了它,要么有另一个更简单的解决方案在我面前摆在我面前,你们所有人(知道你们在做什么的人)都在使用它


**对于可以完全包含完整字符的固定大小字符编码,这些问题不会出现——UTF-32显然是唯一具有这些特征的选项(或将自身限制为ASCII或类似标准的专用环境)


所以,我的问题是: “如何测试空白、可打印等内容,而不会出现两个问题:

1) 签名扩展,和
2) 可变宽度字符问题

毕竟,大多数字符编码都是可变宽度的:UTF-7、UTF-8、UTF-16,以及Shift JIS等旧标准。如果编译器将字符视为有符号8位单元,即使扩展ASCII也可能存在简单的符号扩展问题

请注意: 无论字符类型大小如何,大多数字符编码方案都是错误的

这个问题在标准C库中,以及C++标准库中,它仍然试图绕过char和W查尔格,而不是在各种iStaseIsPrices等实现中使用字符串迭代器。 实际上,正是这些类型的函数打破了std::string的通用性。如果它只在存储单元中工作,而不试图假装理解存储单元作为逻辑字符的含义(如isspace),则抽象将更加诚实,并将迫使我们程序员到其他地方寻找有效的解决方案

非常感谢。 所有参与讨论的人。在这次讨论和我之间,我对这些问题有了更好的处理。虽然没有简单的答案,但每一点理解都会有所帮助

如何以不受两个问题影响的方式测试空白、可打印等:
1) 符号扩展
2) 可变宽度字符问题
毕竟,不管程序员是否意识到,所有常用的Unicode编码都是可变宽度的:UTF-7、UTF-8、UTF-16,以及Shift-JIS等旧标准

显然,您必须使用支持Unicode的库,因为您已经(正确地)演示了C++ 03标准库不是,C++ 11库是改进的,但对于大多数用法来说仍然不够好。有些OS有32位WCHARGET,这使得它们能够正确处理UTF32,但是这是一种实现,并且不是由C++保证的,对于许多Unicode任务来说,远远不够,例如通过字形迭代。s(字母)






还有更多


如果问题不是关于具体的字符测试,而是关于一般的代码实践:做你的框架所做的任何事情。如果你是为linux/QT/网络编写代码,请将所有内容都放在UTF-8内部。如果你是使用Windows编写代码,请将所有内容都放在UTF-16内部。如果你需要处理代码点,请将所有内容都放在UTF-16内部UTF-32中的y。否则(对于可移植的通用代码),做任何你想做的事,因为不管怎样,你都必须为某些操作系统或其他操作系统进行翻译。

我没有对Qt库的国际化功能进行过太多测试,但据我所知,QString完全支持unicode,并且正在使用QChar,它们是unicode字符。我不知道它们的内部实现,但我希望不会他的意思是QChar是可变大小的字符


将自己绑定到像Qt这样的大框架上只是为了使用字符串是很奇怪的。

在任何情况下,将EOF以外的负值传递给
isspace
和其他字符宏都是无效的。如果您有一个
char c
,并且您想测试它是否是一个空格,请执行
isspace((unsigned char)c)
。这涉及扩展(通过零扩展)。
isspace(*pchar)
完全错误——不要写它,当你看到它时不要让它站起来。如果你训练自己在看到它时惊慌失措,那么就不那么难看到它

fgetc
(例如)已返回EOF或读取为
无符号字符的字符,然后转换为
int
,因此该值没有符号扩展问题

不过,这真的是琐事,因为标准字符宏不包括Unicode或多字节编码。如果你想正确处理Unicode,那么你需要一个Unicode库。我没有研究C++11或C1X在这方面提供了什么,除了C++11有
std::u32string
这听起来很有希望。在此之前swer就是用im的东西
template<std::ctype_base::mask mask>
class Is  //  Must find a better name.
{
    std::locale myLocale;
            //< Needed to ensure no premature destruction of facet
    std::ctype<char> const* myCType;
public:
    Is( std::locale const& l = std::locale() )
        : myLocale( l )
        , myCType( std::use_facet<std::ctype<char> >( l ) )
    {
    }
    bool operator()( char ch ) const
    {
        return myCType->is( mask, ch );
    }
};

typedef Is<std::ctype_base::space> IsSpace;
//  ...
bool isspace_utf8(const char* pChar)
{
    uint32_t codePoint = decode_char(*pChar);
    return is_unicode_space(codePoint);
}