我很惊讶这个编译...它肯定会在我的系统上引发警告,我看到“ASO00D”打印出来。
#include <stdio.h>
void main(void) {
unsigned char fileData[] = {'^A','S','O','0','0','^D'};
printf("%s\n", fileData);
}
$ gcc x.c -o x -Wall
x.c:3:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main(void) {
^
x.c: In function ‘main’:
x.c:4:30: warning: multi-character character constant [-Wmultichar]
unsigned char fileData[] = {'^A','S','O','0','0','^D'};
^
x.c:4:30: warning: large integer implicitly truncated to unsigned type [-Woverflow]
x.c:4:51: warning: multi-character character constant [-Wmultichar]
unsigned char fileData[] = {'^A','S','O','0','0','^D'};
^
x.c:4:51: warning: large integer implicitly truncated to unsigned type [-Woverflow]
$ ./x
ASO00D
不要忘记使用 -Wall 并阅读警告 - 它们很有帮助!
^A 不是可打印字符,因此printf()(或更准确地说是您的终端)将无法正确呈现它,即使这已按您的预期工作。
此外,正如 Michael Walz 在 cmets 中所指出的,您应该始终使用 nul 字符终止字符串 - \0。在上面的示例中,您冒着超出数组末尾的风险,因此 未定义的行为。
您实际尝试使用的是控制字符的常见人类可读符号。
Ctrl + A 通常打印为^A。
这并不意味着您可以将 ^A 放入 C 字符中并期望它能够工作 - 首先它是两个字符...^ 和 A。
相反,您应该参考ASCII table,并了解按下 Ctrl 或 Shift 实际上会修改按下的键。 [我不是指键盘扫描码]。
a 0x61 0b01100001
A 0x41 0b01000001
^A 0x01 0b00000001
- 按 A 会生成
a (0x61)
- 按 Shift + A 会生成
A (0x61 & ~0x20 = 0x41)
- 按 Ctrl + A 会生成
^A (0x61 & ~0x60 = 0x01)
尝试改用这个:
unsigned char fileData[] = {0x01,'S','O','0','0',0x04,'\0'};
但是,即使这样printf()“正确”也不会。
尝试使用循环,如下所示:(注意 isprint() 和 iscntrl() 测试)
#include <stdio.h>
#include <ctype.h>
void main(void) {
int i;
unsigned char fileData[] = {0x01,'S','O','0','0',0x04,'\0'};
printf("%s\n", fileData);
for (i = 0; i < sizeof(fileData) - 1; i++) {
printf("%3d: 0x%02X ", i, fileData[i]);
if (isprint(fileData[i])) {
printf("%c", fileData[i]);
} else if (iscntrl(fileData[i])) {
printf("^%c", fileData[i] + 'A' - 1);
} else {
printf(".");
}
printf("\n");
}
}
$ gcc x.c -o x -Wall
x.c:4:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main(void) {
^
$ ./x
SO00
0: 0x01 ^A
1: 0x53 S
2: 0x4F O
3: 0x30 0
4: 0x30 0
5: 0x04 ^D