警告:格式字符串在字符串正文中包含“\0”[-Wformat]
warning: format string contains '\0' within the string body [-Wformat]
我的代码中有一个使用 awk 的 system()
命令。我不知道如何解决 \x00
十六进制值的问题。显然他们需要以不同的方式终止,但这超出了我所知道的范围。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char command[128];
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
system(command);
}
Warnings/Errors:
> test.c:8:56: warning: format string contains '[=11=]' within the string body [-Wformat]
> snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
> /usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
> __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
^
1 warning generated.
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
抱歉,如果之前有人问过这个问题,我在搜索如何解决这个问题时找不到任何相关信息,谢谢...
考虑 C 字符串文字 "\xAB"
。此字符串文字包含一个字节,而不是 4 个字节。类似地,"\x00"
是一个包含一个字节的字符串文字,该字节是一个空字节。 Clang 会警告您这一点,因为空字节结束了 C 字符串——它之后的每个字符都会被 snprintf
.
等库函数忽略
在您的 awk 代码中,有一个 awk 字符串文字,用双引号括起来。你写了 …\"\xBC\x00\x00\xAB\"…
,双引号前面有反斜杠,否则双引号会被解释为结束 C 字符串文字。同样,如果你想在 awk 代码中以一个反斜杠结束(更准确地说,在 shell 命令中),你需要在它前面加上另一个反斜杠。换句话说,你需要加倍你的反斜杠。
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
请注意,您的程序还有另一个引用问题:它将其参数解释为 shell 代码片段,而不是文件名。只有当文件名不包含任何 shell 特殊字符时,两者才会重合。例如,./your_program Jack.txt
有效,但 ./your_program "O'Leary.txt"
无效。要使其工作,您需要修改参数以保护 shell 个特殊字符。
(另一个问题是您不检查 snprintf
是否成功。它可能会溢出 — 您应该根据参数的长度动态分配必要的大小(不要忘记考虑如果参数包含特殊字符,则额外引用)。)
C 字符串文字中的字符序列 '\'
、'x'
、'0'
、'0'
表示单个 char
,数值为零。因此,由两个字符串文字 "\x00"
和 "[=18=]"
表示的 char
数组具有相同的大小和内容:两个 char
(包括终止符),均为零。当用作 C 字符串时,两者都等同于空字符串,因为索引零处的零字符用作字符串终止符。
您的编译器警告您传递给 snprintf()
的字符串文字包含内部空字节(实际上它有两个),这可能会导致它无法按您的预期进行解释。如果你的意思是字符串中的 \xhh
序列被视为四个文字字符的序列,那么你必须加倍反斜杠:
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
我的代码中有一个使用 awk 的 system()
命令。我不知道如何解决 \x00
十六进制值的问题。显然他们需要以不同的方式终止,但这超出了我所知道的范围。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char command[128];
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
system(command);
}
Warnings/Errors:
> test.c:8:56: warning: format string contains '[=11=]' within the string body [-Wformat]
> snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
> /usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
> __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
^
1 warning generated.
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
抱歉,如果之前有人问过这个问题,我在搜索如何解决这个问题时找不到任何相关信息,谢谢...
考虑 C 字符串文字 "\xAB"
。此字符串文字包含一个字节,而不是 4 个字节。类似地,"\x00"
是一个包含一个字节的字符串文字,该字节是一个空字节。 Clang 会警告您这一点,因为空字节结束了 C 字符串——它之后的每个字符都会被 snprintf
.
在您的 awk 代码中,有一个 awk 字符串文字,用双引号括起来。你写了 …\"\xBC\x00\x00\xAB\"…
,双引号前面有反斜杠,否则双引号会被解释为结束 C 字符串文字。同样,如果你想在 awk 代码中以一个反斜杠结束(更准确地说,在 shell 命令中),你需要在它前面加上另一个反斜杠。换句话说,你需要加倍你的反斜杠。
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
请注意,您的程序还有另一个引用问题:它将其参数解释为 shell 代码片段,而不是文件名。只有当文件名不包含任何 shell 特殊字符时,两者才会重合。例如,./your_program Jack.txt
有效,但 ./your_program "O'Leary.txt"
无效。要使其工作,您需要修改参数以保护 shell 个特殊字符。
(另一个问题是您不检查 snprintf
是否成功。它可能会溢出 — 您应该根据参数的长度动态分配必要的大小(不要忘记考虑如果参数包含特殊字符,则额外引用)。)
C 字符串文字中的字符序列 '\'
、'x'
、'0'
、'0'
表示单个 char
,数值为零。因此,由两个字符串文字 "\x00"
和 "[=18=]"
表示的 char
数组具有相同的大小和内容:两个 char
(包括终止符),均为零。当用作 C 字符串时,两者都等同于空字符串,因为索引零处的零字符用作字符串终止符。
您的编译器警告您传递给 snprintf()
的字符串文字包含内部空字节(实际上它有两个),这可能会导致它无法按您的预期进行解释。如果你的意思是字符串中的 \xhh
序列被视为四个文字字符的序列,那么你必须加倍反斜杠:
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);