控制C缓冲区中的字符

时间:2018-02-07 12:37:48

标签: c linux ascii

我需要在socket上传输以下内容。

^ASO00^D

我试图将它们存储在缓冲区中:

unsigned char fileData[] = {'^A','S','O','0','0','^D'},

当我打印fileData时,它不会打印ASCII字符。

 printf("%s\n", fileData);

只打印“S000”。

如何将控制字符保存在缓冲区

但是当我将其存储在一个文件中并从文件中读取时,控制字符就会被打印

2 个答案:

答案 0 :(得分:3)

我对此编译感到惊讶......它肯定会在我的系统上发出警告,并且我看到“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在评论中指出的那样,你应该总是终止一个带有空字符的字符串 - \0。在上面的示例中,您可能会跑过数组的末尾,因此未定义的行为

您实际尝试使用的是控制字符的常用人类可读符号。

Ctrl + A 通常打印为^A

这并不意味着您可以将^A放入C字符并期望它可以正常工作 - 首先它是两个字符...... ^A

相反,您应该参考ASCII table,并了解按 Ctrl Shift 实际修改按下的键。 [我不是指键盘扫描码]

 a  0x61  0b01100001
 A  0x41  0b01000001
^A  0x01  0b00000001
  • A 会产生a0x61
  • Shift + A 会产生A0x61 & ~0x20 = 0x41
  • Ctrl + A 会产生^A0x61 & ~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

答案 1 :(得分:0)

您正尝试将字节值存储在数组中:

GotoSecondViewCommand