麻烦的chr和编码问题

时间:2018-08-06 17:02:33

标签: python python-3.x character-encoding

我想知道为什么以下代码的输出正在更改:

int makeBinary(int** img, int height, int width)
{
    int threshold = 0;
    unsigned long int sum = 0;
    for (int k = 0; k < width; k++)
    {
        sum = sum + img[1][k] + img[2][k] + img[3][k] + img[4][k] + img[5][k];
    }
    threshold = sum / (width * 5);
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            img[i][j] = img[i][j] > threshold ? 1 : 0;
        }
    }
    return threshold;
}


// Count pixels - find length of cavity here
int measureCavity(int &x, int& width, int &y, int &height, int **img)
{
    double mean = 1.;
    int maxcount = 0;
    int pxcount = 0;
    int i = x - 1;
    int j;
    int pxsum = 0;
    for (j = 0; j < height - 2; j++)
    {
        while (mean > 0.0)
        {
            for (int ii = i; ii > i - 4; ii--)
            {
                pxsum = pxsum + img[ii][j] + img[ii][j + 1];
            }
            mean = pxsum / 4.;
            pxcount += 2;
            i += 2;
            pxsum = 0;
        }
        maxcount = std::max(maxcount, pxcount);
        pxcount = 0;
        j++;
    }

    return maxcount;
}

在output.txt中,输出为:(<-字符未显示,但它的方框中有两个零在顶行,一个8和一个0在底行..)但是在我的IDE中,输出是空方格:□。有人可以解释为什么这两个输出不匹配吗?

我正在使用Ubuntu 16.04,而我的IDE是PyCharm CE。另外,如果我尝试编码,情况也不会改变:

N = 128

print(chr(N))

file = open('output.txt', 'w')
file.write(chr(N))
file.close()

2 个答案:

答案 0 :(得分:2)

您的代码,文件或其他任何内容都没有问题。

您正在正确地将chr(128)(又名U+0080)(又称Unicode控制字符)编写为UTF-8。该文件将采用该字符的UTF-8编码(两个字节\xc2\x80)。

当您在未指定的第一个程序中查看它时(也许只是cat将其放置到您的终端是什么?),它正确地将这两个字节读取为字符U + 0800的UTF-8。并显示其所选字体对该字符具有的任何图像。

在PyCharm中查看它时,它正确读取U + 0800并使用其选定的字体显示它。

唯一的区别是他们使用的是不同的字体。对于不可打印的控制字符,不同的字体会做不同的事情。 (此字符没有标准的呈现方式-在Unicode中没有特定的含义,但是映射到Latin-1补码字符0x80,该字符定义为控制字符“ PAD”,是“ Padding Character”(填充字符)的缩写。 1 )不同的东西可能有用,所以不同的字体会做不同的事情:

  • 向您显示控制字符的十六进制值可能对例如在shell上使用Unicode的人员很有用,因此将您的终端(或任何其他方式)配置为使用显示方式的字体。
  • 仅向您显示这是您可能不希望使用通用替换框 2 打印的内容,因此PyCharm配置有可以做到这一点的字体。
  • li>
  • 仅将其显示为空格也是合理的,尤其是在固定宽度的字体中。这是我在终端上cat或从我的Python REPL print获得它时所得到的。
  • 在框中显示控制字符(PAD)的传统Latin-1名称也很有用。这就是Unifont的东西。
  • 出于向后兼容性的原因,将其显示为欧元符号对于处理一堆旧Java或Win32代码的情况可能很有用。 3

1。从技术上讲,这不再是真的。 Unicode根据ISO-15924代码998(“ Zyyy:未确定脚本的代码”)对它进行了定义,而完全不作为ISO-8859的一部分。但是实际上,它要么是PAD,要么是一个不确定的无意义字符,它并没有多大用处。

2。您实际粘贴到问题中的不是U+0080也不是U+FFFD,而是U+25A1,又称“白方块”。大概是PyCharm意识到它的字体没有U+0080的字形,而是手动替换了U+25A1,或者从剪贴板到浏览器再到Stack Overflow的链上的东西都做了同样的事情……

3。创建欧元符号后,但在Unicode 2.1添加U + 20AC和ISO-8859添加Latin-9编码之前,人们不得不采用某种方式来显示欧元。两种最常见的非标准编码之一是使用Latin-1 80 / Unicode U+0080。 (另一个是A4 / U+00A4)。还有一些针对Unicode 2.0编写的Java和Win32代码应用程序,使用的是这种hack(仍在野外使用)和字体来支持它们。

答案 1 :(得分:1)

Python使用UTF-8进行编码。函数chr返回每个输入值的对应字符。但是,不能显示所有字符。有些字符仅用于控制目的。在您的情况下,填充字符为128。由于无法显示,因此每种环境都将其区别对待。因此,文件编辑器以十六进制显示其值,而IDE根本不显示它。尽管如此,编辑器和IDE都意识到它是什么字符。