【问题标题】:What does 'y' in the output stand for in C?输出中的 'y' 在 C 中代表什么?
【发布时间】:2009-11-15 17:18:31
【问题描述】:

我有一个问题,我在循环中构造了一个字符串,该字符串的输出将显示该字符串和一个字符“y”,上面有两个点作为最后一个字符。

那是什么?

我在这个函数中创建字符串:

char get_string(char *buf, int ble, FILE *fp, char del)
{
    int i = 0;
    int c;
    char    result;

    memset(buf, 0, BUFLEN);

    do {

        c = fgetc(fp);

        if (c == del) {
            buf[i] = '\0';
            result = c;
            break;
        } else if(c == '\n') {
            buf[i] = '\0';
            result = '\n';
            break;
        } else {
            buf[i] = c;
            i++;
        }

    } while (c != EOF);

    return result;
}

然后在另一个函数中使用buf和结果如下:

char    pair[BUFLEN];
char    end;

do {

        end = get_string(pair, BUFLEN, fp, ';');
        printf("Result: %s\n",pair);

} while (pair != NULL);

上面的最后一次迭代打印出“结果:y”我不知道为什么。

【问题讨论】:

    标签: c string


    【解决方案1】:

    您正在使用do-while 循环,这意味着您在测试EOF 之前正在执行循环主体,因此您最终也将EOF 放入缓冲区中。 EOF 的值 -1 被转换为对应于 ÿ 的字符范围。我建议您切换到更常用的 while 循环,因为它更自然地处理这种情况。

    【讨论】:

      【解决方案2】:

      ÿ 是(在 Unicode 和许多 ISO-8859-? 编码中)具有序数值 0xFF 的字符的字形。该值,也称为十进制的 255,在某些情况下也被用作“文件结尾字符”(又名 EOF)——尽管没有标准将 字符 定义为这样( AFAIK),当您尝试从已用尽的文件(“文件末尾”)中读取更多内容时,许多语言(例如 C)会返回值 -1。

      因此,在实践中,输出中的意外 ÿ 通常意味着您错误地解释了一个旨在表示“某事结束”的字节(一个所有位都设置为 1 的编码字节),就好像它是要显示的文本。

      【讨论】:

      • Small nitpick - 它是 Unicode 代码点 U+00FF 的字形,在 UTF-8 中对应于字节 0xFF
      • @Jesse,在 Unicode 中它可以写成 U+00FF(十进制的序数值 255,十六进制的 FF 等),在 ISO-8859-1 (&c) 中当然可以'不要用'U'前缀写(虽然0xFF仍然是正确的;-),并且UTF-8中的这个代码点被编码为两字节序列,0xC3 0xBF,这与OP的问题无关。
      • 我的错,你说得对,在 UTF-8 中它是一个两字节的序列。但我认为引用 Unicode 代码点的正确方法是 U+00FF,而 0xFF 是指设置了所有位的字节(或只是数字 255)。当然,这只是从阅读有关 Unicode 的点点滴滴而来;我不是专家,所以我很高兴得到纠正。 (例如,维基百科页面仅引用 U+stuff 的代码点)。不过,我可能不应该不假思索地提到 UTF-8 位:)
      • -1 用于误导性解释(C 中没有 EOF“字符”,它没有值 255 或任何其他值;它是带外指示符值)。您没有看到的问题是代码具有通常的初学者错误,即在读取最后一个字符后期望设置 EOF。
      【解决方案3】:

      'y' 上面有两个点是字符 0xFF(在 latin-1 中 - 控制台的默认代码页)。

      0xFF 作为 8 位有符号值是 -1。

      查找您将 -1 打印为 char 的位置(或使用 -1 作为 char 然后打印它)。

      【讨论】:

        【解决方案4】:

        您的if-statement 以 else 结尾,将字符放入缓冲区有两个缺陷:

        1. 它不会过滤掉EOF 特殊的“字符”,它表示流的结束
        2. 它不会通过比较 iBUFLEN 值来检查缓冲区溢出。

        第一个问题是你的ÿ字符的原因,当流结束时,你将EOF字符添加到缓冲区,然后循环终止。

        解决方法是在您的 if-else 语句中添加一个子句以将其过滤掉,如下所示:

        } else if (c != EOF) {
            buf[i] = c;
            i++;
        }
        

        第二个问题你需要在修复之前决定如何处理,但它应该被修复。

        【讨论】:

          【解决方案5】:

          当你“在循环中构造你的字符串”时,你还记得用'\0' 正确终止它吗?

          如果循环将字符分配给字符数组,则最后一个数组项应该是'\0'

          好的,看到代码后,你正在终止字符串。

          编辑

          看起来您在字符串中包含 EOF 字符。这是字符串未正确终止的一种情况。您应该检查 if-else 结构中的 EOF 并正确处理它。

          我注意到的另一件事:

          从函数返回时,您将 int c 分配给 char result。编译器应该警告您,您正试图将较大的数据类型放入较小的数据类型。根据返回值的用途,我会考虑将返回数据类型更改为int

          【讨论】:

            【解决方案6】:

            您没有正确地以空值终止您的字符串。如果从 fp 读取永远不会返回“del”或“\n”并且到达 EOF,则不会有空终止符。你需要修复你的代码。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-04-14
              • 1970-01-01
              • 1970-01-01
              • 2014-10-08
              • 1970-01-01
              • 1970-01-01
              • 2015-04-09
              相关资源
              最近更新 更多