如何在Linux中用C将非ASCII字符压缩为1个字节?

问题描述 投票:4回答:2

我有土耳其语列表。我需要比较一下它们的长度。但是由于某些土耳其语字符不是ASCII,所以我无法正确比较它们的长度。非ASCII土耳其语字符占2个字节。

例如:

#include <stdio.h>
#include <string.h>

int main()
{
    char s1[] = "ab";
    char s2[] = "çş";

    printf("%d\n", strlen(s1)); // it prints 2
    printf("%d\n", strlen(s2)); // it prints 4

    return 0;
}

我的朋友说,可以在Windows中使用以下代码行来做到这一点:

system("chcp 1254");

他说,它将土耳其字符填充到扩展的ASCII表中。但是,它在Linux中不起作用。

在Linux中有没有办法做到这一点?

c linux ascii non-ascii-characters
2个回答
2
投票

一种可能是使用宽字符串存储单词。它不会将字符存储为一个字节,但是可以解决您的主要问题。获得一组使用您的语言的功能。该程序如下所示:

#include <stdio.h>
#include <string.h>
#include <wchar.h>

int main()
{
    wchar_t s1[] = L"ab";
    wchar_t s2[] = L"çş";

    printf("%d\n", wcslen(s1)); // it prints 2
    printf("%d\n", wcslen(s2)); // it prints 2

    return 0;
}

4
投票

是2017年,很快是2018年。所以使用UTF-8 everywhere(在最近的Linux发行版中,UTF-8是最常见的编码,对于大多数locale(7) -s来说,当然也是系统上的默认编码);当然,以UTF-8编码的Unicode字符可能具有一到六个字节(因此,某些UTF-8字符串中的Unicode字符数是strlen给出的not)。考虑使用某些UTF-8库,例如libunistring(或其他库,例如Glib中的库)。

chcp 1254是某些Windows特定的东西,与UTF-8系统无关。所以就算了。

如果您编写GUI应用程序,请使用窗口小部件工具箱,例如GTKQt。它们都处理Unicode,并且能够接受(或转换为UTF-8)。请注意,即使只是显示Unicode(例如某些UTF-8或UTF-16字符串)也不是一件容易的事,因为字符串可能会混用例如阿拉伯语,日语,西里尔字母和英语单词(您需要从左到右和从右到左两个方向显示),因此最好找到一个库(或其他工具,例如支持UTF-8的terminal emulator)为此。

如果您碰巧得到了一个文件,则需要知道它正在使用的编码(而这仅仅是一些convention,您需要获取并遵循它)。在some情况下,file(1)命令可能会帮助您猜测该编码,但是您需要了解用于制作该文件的编码约定。如果它不是UTF-8编码的,则可以使用iconv(1)命令对其进行转换(前提是您知道源编码)。

© www.soinside.com 2019 - 2024. All rights reserved.