错误:十六进制逃逸序列超出范围,写功能是从3个区域读取12个字节

发布于 2025-02-13 21:49:15 字数 299 浏览 1 评论 0 原文

我的代码引起了问题:

if (write(STDOUT_FILENO, "\x1b999C\x1b999B", 12) != 12)
        return -1;

在这里,write()来自< unistd.h>

因此,在编译时提供了两个警告。 “ \ x1b999c \ x1b9999b” 不超出范围,'写''读数12字节从大小3的区域。

我基本上试图做的是将光标移至底部,终端窗口的右角。为什么那里有这些警告?

My code which is causing problems:

if (write(STDOUT_FILENO, "\x1b999C\x1b999B", 12) != 12)
        return -1;

Here, write() comes from <unistd.h>.

So, on compiling it providing two warnings. That hex escape sequence, "\x1b999C\x1b999B" is out of range and ‘write’ reading 12 bytes from a region of size 3.

What I am basically trying to do is move the cursor to the bottom right corner of the terminal window. Why are those warnings there ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请爱~陌生人 2025-02-20 21:49:15

八分之一仅使用一到三个(八进制)数字 - &nbsp; “ \ 033999c” 是5个字符加上一个null字节。

十六进制逃脱使用的数字数量如 \ x 序列。因此,“ \ x1b999c” 包含一个单个十六进制字符常数。

参见§6.4.4.4.4用于规格。

至少有两个可能的修复程序。一种是编码 \ x1b \ 033 (或 \ 33 - 它们是相同的,尽管如果之后的文本\ x1b 777a 而不是 999c ,那么三位数的八位ovene是必需的

if (write(STDOUT_FILENO, "\033999C\033999B", 10) != 10)

。串联:

if (write(STDOUT_FILENO, "\x1B" "999C" "\x1B" "999B", 10) != 10)

这是因为在 - 第5阶段转换逃脱序列,第6阶段结合了相邻的字符串文字

。这是10个非挂钩字符 - 如果您打算编写字节0x01,然后是5个字符(两次),那么12个字符更有意义,并且您需要更改字符串中断的地方

。 > 11 :

#include <stdio.h>

int main(void)
{
    char data[] = "\x1b" "999C" "\x1b" "999B";
    printf("%zu\n", sizeof(data));
    return 0;
}

删除序列,GCC投资:

xe43.c: In function ‘main’:
xe43.c:5:19: error: hex escape sequence out of range [-Werror]
     char data[] = "\x1b999C\x1b999B";
                   ^~~~~~~~~~~~~~~~~~
xe43.c:5:19: error: hex escape sequence out of range [-Werror]
cc1: all warnings being treated as errors

我使用 Werror 选项进行编译,否则,只有警告没有 -werror 并运行,它会产生答案3,而不是11。

Octal escapes use one to three (octal) digits only — "\033999C" is 5 characters plus a null byte.

Hex escapes use as many hex digits as follow the \x sequence. Therefore, "\x1b999C" contains a single hex character constant.

See §6.4.4.4 Character constants in the C11 standard for the specification.

There are at least two possible fixes. One is to encode \x1B as \033 (or \33 — they're the same, though if the text after the \x1B was 777A instead of 999C, then the triple-digit octal escape would be necessary.

if (write(STDOUT_FILENO, "\033999C\033999B", 10) != 10)

A second is to split the string and use string concatenation:

if (write(STDOUT_FILENO, "\x1B" "999C" "\x1B" "999B", 10) != 10)

This works because of what is specified in §5.1.1.2 Translation phases — where phase 5 converts escape sequences and phase 6 combines adjacent string literals.

I observe that there are 10 non-null characters in this — if you intended to write the byte 0x01 followed by 5 characters (twice), then 12 makes more sense, and you need to alter where the strings break, of course.

This test code prints 11:

#include <stdio.h>

int main(void)
{
    char data[] = "\x1b" "999C" "\x1b" "999B";
    printf("%zu\n", sizeof(data));
    return 0;
}

Remove the " " sequences, and GCC complains:

xe43.c: In function ‘main’:
xe43.c:5:19: error: hex escape sequence out of range [-Werror]
     char data[] = "\x1b999C\x1b999B";
                   ^~~~~~~~~~~~~~~~~~
xe43.c:5:19: error: hex escape sequence out of range [-Werror]
cc1: all warnings being treated as errors

I compile with the -Werror option; otherwise, it would only be a warning. If compiled without -Werror and run, it produces the answer 3, not 11.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文