相关疑难解决方法(0)

std :: wstring VS std :: string

我无法理解之间的差异std::stringstd::wstring.我知道wstring支持Unicode字符等宽字符.我有以下问题:

  1. 我什么时候应该std::wstring用完std::string
  2. 可以std::string保存整个ASCII字符集,包括特殊字符吗?
  3. std::wstring由所有流行的C++编译器的支持?
  4. 什么是" 广角 "?

c++ string unicode c++-faq wstring

716
推荐指数
7
解决办法
29万
查看次数

C++将字符串(或char*)转换为wstring(或wchar_t*)

string s = "????";
wstring ws = FUNCTION(s, ws);
Run Code Online (Sandbox Code Playgroud)

我如何将s的内容分配给ws?

搜索谷歌并使用了一些技术,但他们无法分配确切的内容.内容失真.

c++ string wstring

157
推荐指数
11
解决办法
24万
查看次数

C++ 11中的Unicode

我一直在读一些关于Unicode的主题 - 特别是UTF-8 - (非)支持C++ 11,我希望Stack Overflow上的大师可以向我保证我的理解是正确的,或指出我在哪里误解或错过了某些情况.

简短摘要

首先,好的:您可以在源代码中定义UTF-8,UTF-16和UCS-4文字.此外,<locale>标头包含几个std::codecvt可以在UTF-8,UTF-16,UCS-4和平台多字节编码之间进行转换的实现(虽然API看起来很温和,但不是直截了当).这些codecvt实现可以imbue()在流上进行,以允许您在读取或写入文件(或其他流)时进行转换.

[ 编辑: Cubbi在评论中指出我忽略了提到<codecvt>标题,它提供了std::codecvt不依赖于语言环境的实现.此外,std::wstring_convertwbuffer_convert函数可以使用这些codecvt来直接转换字符串和缓冲区,而不是依赖于流.

C++ 11还包括C99/C11 <uchar.h>标头,其中包含将来自平台多字节编码(可能是或不是UTF-8)的单个字符转换为UCS-2和UCS-4的功能.

但是,这是关于它的程度.虽然你当然可以将UTF-8文本存储在a中std::string,但我无法看到任何对它有用的东西.例如,除了在代码中定义文字之外,您不能将字节数组验证为包含有效的UTF-8,您无法找到长度(即Unicode字符的数量,对于某些"字符"的定义)包含UTF-8 std::string,并且不能std::string以字节为单位以任何方式迭代a .

同样,即使添加C++ 11 std::u16string也不支持UTF-16,但只支持较旧的UCS-2 - 它不支持代理对,只留下BMP.

意见

鉴于UTF-8是在几乎所有Unix派生系统(包括Mac OS X和*Linux)上处理Unicode的标准方式,并且已经在很大程度上成为Web上事实上的标准,现代C++中缺乏支持似乎像一个相当严重的遗漏.即使在Windows上,新std::u16string功能并不真正支持UTF-16 这一事实似乎有些令人遗憾.

*由于在评论中指出,并明确提出在这里的Mac OS使用UTF-8的BSD衍生的部分,而可可使用UTF-16.

问题

如果你设法阅读了所有这些,谢谢!只是几个简单的问题,因为这毕竟是Stack Overflow ...

  • 以上分析是否正确,或者我是否缺少任何其他支持Unicode的设施?

  • 在过去几年中,标准委员会在快速推进C++方面做得非常出色.他们都很聪明,我认为他们很清楚上述缺点.是否有一个众所周知的原因,即Unicode支持在C++中仍然很差?

  • 展望未来,是否有人知道有任何纠正这种情况的建议?快速搜索isocpp.org似乎没有透露任何信息.

编辑:感谢大家的回复.我不得不承认,我发现它们有点令人沮丧 - 看起来现状在不久的将来不太可能改变.如果在认知方面存在共识,似乎完全的Unicode支持太难了,并且任何解决方案必须重新实现大多数ICU才被认为是有用的.

我个人不同意这一点; 我认为可以找到有价值的中间立场.例如,对于UTF-8和UTF-16的验证和归一化算法是由Unicode财团以及指定的,并且可以通过标准库中,比方说自由函数,一个被提供std::unicode的命名空间.仅这些对于需要与期望Unicode输入的库接口的C++程序来说是一个很大的帮助.但基于下面的答案(微笑,必须说,带着一丝苦涩),似乎Puppy关于这种有限功能的提议并不受欢迎.

c++ unicode utf-8 utf-16 c++11

57
推荐指数
1
解决办法
4177
查看次数

从字符串文字到'char*'的弃用转换

我有一个程序声明一个像这样的字符串数组:

char *colors[4] = {"red", "orange", "yellow", "blue"};
Run Code Online (Sandbox Code Playgroud)

但是我得到了上面的编译器警告.它编译但我宁愿使用非弃用的方式(如果有的话).我试图找出它意味着什么,但我似乎无法弄明白.我听说'char'工作之前使用'const',但如果有人能解释错误的含义,那将会有所帮助.谢谢.

c++ string char literals deprecated

55
推荐指数
3
解决办法
4万
查看次数

C++ 11 Regex中的UTF-8字符范围

这个问题是Do C++ 11正则表达式与UTF-8字符串一起使用的扩展吗?

#include <regex>  
if (std::regex_match ("?", std::regex("?") ))  // "\u4e2d" also works
  std::cout << "matched\n";
Run Code Online (Sandbox Code Playgroud)

该程序在Mac Mountain Lion上编译,clang++具有以下选项:

clang++ -std=c++0x -stdlib=libc++
Run Code Online (Sandbox Code Playgroud)

上面的代码有效.这是一个标准范围正则表达式,"[?-?????]"用于匹配任何日语汉字或汉字.它适用于Javascript和Ruby,但即使使用类似的版本,我似乎也无法使用C++ 11工作[\u4E00-\u9fa0].下面的代码与字符串不匹配.

if (std::regex_match ("?", std::regex("[?-?????]")))
  std::cout << "range matched\n";
Run Code Online (Sandbox Code Playgroud)

改变语言环境也没有帮助.有任何想法吗?

编辑

所以我发现如果你添加+到最后,所有范围都有效.在这种情况下[?-?????]+,但如果你添加{1} [?-?????]{1}它不起作用.而且,它似乎超越了它的界限.它不会匹配拉丁字符,但它会匹配?这是\u306f?\u3041.他们都躺在下面\u4E00

nhahtdh还提出了regex_search,它也可以在不增加的情况下工作,+但它仍然会遇到与上面相同的问题,因为它会超出其范围.同时也使用了语言环境.Mark Ransom建议它将UTF-8字符串视为一组愚蠢的字节,我认为这可能就是它所做的.

进一步推动UTF-8变得混乱的理论[a-z]{1}[a-z]+匹配a,但只[?-?????]+匹配任何角色,而不是[?-?????]{1}.

c++ regex unicode utf-8 c++11

30
推荐指数
1
解决办法
5617
查看次数

c ++字符串文字仍然令人困惑

我一直在阅读一些关于Unicode的文章,并意识到我仍然对这件事做些什么感到困惑.

作为Windows平台上的c ++程序员,给予我的学科与任何教师大致相同:始终使用Unicode字符集; 如果可能的话,将其模板化或使用TCHAR; 喜欢wchar_t,std :: wstring over char,std :: string.

#include <tchar.h>
#include <string>
typedef std::basic_string<TCHAR> tstring;
 // ...
static const char* const s_hello = "??"; // bad
static const wchar_t* const s_wchar_hello = L"??" // better
static LPCTSTR s_tchar_hello = TEXT("??") // even better
static const tstring s_tstring_hello( TEXT("??") ); // best
Run Code Online (Sandbox Code Playgroud)

不知怎的,我搞砸了,我引导自己相信如果我说"某事",那就意味着它是ASCII格式的,如果我说L"某事"就是Unicode.然后我读到了这个:

类型wchar_t是一种不同的类型,其值可以表示支持的语言环境(22.3.1)中指定的最大扩展字符集的所有成员的不同代码.类型wchar_t应具有与其他整数类型之一相同的大小,符号和对齐要求(3.11),称为其基础类型.类型char16_t和char32_t分别表示与uint_least16_t和uint_least32_t相同的大小,符号和对齐的不同类型,称为基础类型.

所以呢?如果我的语言环境从代码页949开始,那么wchar_t的扩展是从949 + 2 ^(sizeof(wchar_t)*8)?它说话的方式听起来像'我不在乎你的c ++实现是使用UTF编码还是什么'.

至少,我可以理解一切都取决于应用程序所在的语言环境.因此我测试了:

#define TEST_OSTREAM_PRINT(x) \
std::cout << "----" << std::endl; \
std::cout << "cout : " << x << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ unicode

9
推荐指数
1
解决办法
1068
查看次数

utf-8中std :: string的子串?C++ 11

我需要获取std :: string中前N个字符的子字符串,假定为utf8.我学到了.substr不起作用的艰难方式......正如......期待的那样.

参考:我的字符串可能如下所示:任务:\n \n1亿2千万匹

c++ utf-8 stdstring substr c++11

6
推荐指数
1
解决办法
6901
查看次数

错误C2196:案例值'?' 已被占用

好吧,在代码中使用Visual Studio Ultimate 2012(可能与ANSI,unicode等问题)构建时出现了奇怪的错误...

switch (input[index])
{
    case '?': // Alef Hebrew character
        if (/*conditional*/) 
        {
            // Do stuff.
        }
    break;

    case '?': // Beth Hebrew character
        if (/*conditional*/)
        {
            //Do stuff
        }
    break;

    default:
    {
            //Do some other stuff.
    }
    break;

}
Run Code Online (Sandbox Code Playgroud)

第二个案例参数生成......

Error C2196: case value '?' already used
Run Code Online (Sandbox Code Playgroud)

如果可能,简单修复.

c c++

4
推荐指数
1
解决办法
1109
查看次数

clang std :: isspace编译错误

以下代码在VS 2015(更新3)和gcc 6.3(C++ 14)上编译正常,没有任何问题.

#include <string>
#include <locale>

int main()
{
    std::u16string ustr = u"Android";

    bool var = std::isspace(ustr[0],std::locale());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,在clang/Xcode上它失败并出现以下错误

Error(s):
source_file.cpp:8:10: warning: unused variable 'var' [-Wunused-variable]
    bool var = std::isspace(ustr[0],std::locale());
         ^
In file included from source_file.cpp:2:
In file included from /usr/include/c++/v1/locale:182:
/usr/include/c++/v1/__locale:705:44: error: implicit instantiation of undefined template 'std::__1::ctype<char16_t>'
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
                                           ^
source_file.cpp:8:21: note: in instantiation of function template specialization 'std::__1::isspace<char16_t>' requested here
    bool var = std::isspace(ustr[0],std::locale());
                    ^
/usr/include/c++/v1/__locale:427:53: note: template is …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 clang++ c++14

3
推荐指数
2
解决办法
535
查看次数

读取多语言文件 - wchar_t vs char?

了解 unicode、语言环境、宽字符和转换对我来说是一次可怕的经历。

我需要读取包含俄语和英语,中国和乌克兰字符的文本文件一次全部

我的方法是以字节块读取文件,然后对块进行操作,在单独的线程上进行快速读取。(关联)

这是使用 std::ifstream.read(myChunkBuffer, chunk_byteSize)

但是,我知道如果我坚持使用char.


就此而言,我将一切都转化wchar_t为最佳状态并希望得到最好的结果。

我也知道Sys.setlocale(locale = "Russian") (链接),但它不是将每个字符解释为俄语吗?当我解析字节时,我不知道何时在我的 4 种语言之间切换。

在 Windows 操作系统上,我可以创建一个 .txt 文件并写上“??????!你好!” 在程序 Notepad++ 中,它将保存文件并以相同的字母重新打开。它是否以某种方式在每个字符后秘密添加隐形标记,以了解何时解释为俄语,何时解释为英语?


我目前的理解是:将所有内容都作为wchar_t(双字节),将任何文件解释为 UTF-16(双字节) - 是否正确?

另外,我希望保持代码跨平台。

对不起菜鸟

c++

3
推荐指数
1
解决办法
1883
查看次数

源文件编码或执行字符集会改变 wchar_t 内部保存的方式吗?

这里的东西(https://docs.microsoft.com/en-us/cpp/build/reference/source-charset-set-source-character-set),我知道所有关于VC ++/source-charset/execution-charset

所以有 3 件事我需要保持不变(如果有任何错误,请纠正我):

  1. 源文件编码
  2. /source-charset 设置(确定编译器如何解释我的源文件)
  3. /execution-charset 设置(确定编译器如何将第 2 阶段的“输出内容”解释为可执行文件。

所以,如果有我保存源文件encodingA,设置/source-charset/execution-charset作为encodingA,并有代码wchar_t c = L'é';char16_t c = u'é'; 或者char32_t c = U'é'

程序会é根据encodingA我在“解释”期间选择的代码单元来更改代码单元吗?

或者é无论我选择什么编码,代码单元都不会改变?

(不要关心控制台输出)

c++

2
推荐指数
1
解决办法
289
查看次数

现在C++中是否有官方TCHAR类型?

如果编写可能使用不同字符类型编译的代码,TCHAR仍然是正确使用的类型,例如std::basic_stringstream<TCHAR>

或者现在有一些官方的C++/STL类型是首选,在wchar_t替换WCHAR,true替换TRUEnullptr替换的方式NULL

我在谈论我正在使用类,如basic_string使用TCHAR显式模板化的情况.

c++ tchar character-encoding c++11

1
推荐指数
1
解决办法
514
查看次数

Unicode字符串上的std :: string和std :: map操作

我想了解常规std::stringstd::map操作如何处理字符串中的Unicode代码单元.

示例代码:

    include <iostream>
    #include "sys/types.h"

    using namespace std;

    int main()
    {

        std::basic_string<u_int16_t> ustr1(std::basic_string<u_int16_t>((u_int16_t*)"????", 4));
        std::basic_string<u_int16_t> ustr2(std::basic_string<u_int16_t>((u_int16_t*)"abcd", 4));

        for (int i = 0; i < ustr1.length(); i++)
            cout << "Char: " << ustr1[i] << endl;

        for (int i = 0; i < ustr2.length(); i++)
            cout << "Char: " << ustr2[i] << endl;

        if (ustr1 == ustr2)
            cout << "Strings are equal" << endl;

        cout << "string length: " << ustr1.length() << "\t" << ustr2.length() << endl; …
Run Code Online (Sandbox Code Playgroud)

c++ unicode

1
推荐指数
1
解决办法
477
查看次数