通过c ++ main char ** args处理不同字符串编码的正确方法是什么?

时间:2015-04-21 19:09:01

标签: c++ linux string encoding utf-8

我需要一些澄清。

问题是我有一个用C ++编写的Windows程序,它使用' wmain'特定于Windows的函数,接受wchar_t **作为其args。所以,有机会将任何你喜欢的命令行参数传递给这样的程序:例如,中文符号,日文符号等等。

老实说,我没有关于此函数通常使用的编码的信息。可能是utf-32,甚至是utf-16。 所以,问题:

  • 什么是不是特定于Windows的,但unix / linux的方式是用标准的main函数实现的?我的第一个想法是关于utf-8编码输入字符串的使用与某种语言环境指定?

  • 有人能给出一个这样的主要功能的简单例子吗? std :: string如何保存中文符号?

  • 当我们像这样访问每个char(byte)时,我们可以像往常一样使用utf-8编码并包含在std :: strings中的中文符号:string_object [i]?

3 个答案:

答案 0 :(得分:2)

免责声明: GOOGLE translate service提供的所有中文字词。

1)使用普通std::string正常进行。 std::string可以保存任何字符编码,参数处理是简单的模式匹配。因此,在安装了中文版程序的中文计算机上,所有需要做的就是将中文版本的标志与用户输入的内容进行比较。

2)例如:

#include <string>
#include <vector>
#include <iostream>

std::string arg_switch = "开关";
std::string arg_option = "选项";
std::string arg_option_error = "缺少参数选项";

int main(int argc, char* argv[])
{
    const std::vector<std::string> args(argv + 1, argv + argc);

    bool do_switch = false;
    std::string option;

    for(auto arg = args.begin(); arg != args.end(); ++arg)
    {
        if(*arg == "--" + arg_switch)
            do_switch = true;
        else if(*arg == "--" + arg_option)
        {
            if(++arg == args.end())
            {
                // option needs a value - not found
                std::cout << arg_option_error << '\n';
                return 1;
            }
            option = *arg;
        }
    }

    std::cout << arg_switch << ": " << (do_switch ? "on":"off") << '\n';
    std::cout << arg_option << ": " << option << '\n';

    return 0;
}

<强>用法:

./program --开关 --选项 wibble

<强>输出:

开关: on
选项: wibble

3)否。

对于UTF-8 / UTF-16数据,我们需要使用ICU等特殊库

对于逐字符处理,您需要使用或转换为UTF-32。

答案 1 :(得分:1)

简而言之:

int main(int argc, char **argv) { setlocale(LC_CTYPE, ""); // ... }

http://unixhelp.ed.ac.uk/CGI/man-cgi?setlocale+3

然后你使用mulitbyte string functions。您仍然可以使用普通std::string来存储多字节字符串,但要注意其中的字符可能跨越多个数组单元格。成功设置区域设置后,您还可以使用宽流(wcin,wcout,wcerr)从标准流中读取和写入宽字符串。

答案 2 :(得分:1)

1)使用linux,您将获得标准main()和标准char。它将使用UTF-8编码。因此,chineese特定字符将包含在具有多字节编码的字符串中 ***编辑:**抱歉,是的:您必须设置默认的“”区域设置like here以及cout.imbue()。*

2)所有经典的main()例子都是很好的例子。如上所述,chineese特定字符将包含在具有多字节编码的字符串中。因此,如果您使用默认的UTF-8语言环境来管​​理这样的字符串,那么cout sream将解释特殊的UTF8编码序列,因为它知道必须在每个序列之间聚集2到6个以产生chineese输出。

3)你可以像往常一样操作琴弦。然而,如果您以字符串长度为例,则存在一些问题:存储器(例如:3字节)与用户看到的字符之间存在差异(例如:仅1)。如果向前或向后移动指针,则相同。您必须确保正确解释mulrtibyte编码,以便不输出无效的编码。

您可能对this other SO question感兴趣。

Wikipedia解释了UTF-8多字节编码的逻辑。在本文中,您将了解任何char u是多字节编码的char,如果:

( ((u & 0xE0) == 0xC0)
       || ((u & 0xF0) == 0xE0)
       || ((u & 0xF8) == 0xF0)
       || ((u & 0xFC) == 0xF8)
       || ((u & 0xFE) == 0xFC) ) 

接下来是一个或几个字符,例如:

((u & 0xC0) == 0x80)

所有其他字符都是ASCII字符(即不是多字节字符)。