【问题标题】:control characters in C BufferC 缓冲区中的控制字符
【发布时间】:2018-02-07 12:37:48
【问题描述】:

我需要通过套接字传输以下内容。

^ASO00^D

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

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

当我打印文件数据时,它不打印 ASCII 字符。

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

它只打印“S000”。

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

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

【问题讨论】:

  • ^A 我假设您的意思是所谓的“control-A”,它对应于ASCII 控制字符SOH?如果我告诉你 ^B 对应于 STX 我相信你将能够弄清楚 ^D 应该是什么。
  • 是的。正是SOH
  • '^A' -> 1, '^D' -> 4
  • '^A' 是多字符字符常量,其值是实现定义的。
  • ^A 是写 ASCII SOH 的常规方式 - 在 C 中,我们将其写为 \001

标签: c linux ascii


【解决方案1】:

我很惊讶这个编译...它肯定会在我的系统上引发警告,我看到“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,并了解按下 CtrlShift 实际上会修改按下的键。 [我不是指键盘扫描码]

 a  0x61  0b01100001
 A  0x41  0b01000001
^A  0x01  0b00000001
  • A 会生成 a (0x61)
  • Shift + A 会生成 A (0x61 &amp; ~0x20 = 0x41)
  • Ctrl + A 会生成 ^A (0x61 &amp; ~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

【讨论】:

    【解决方案2】:

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

    unsigned char fileData[] = {0x01,'S','O','0','0',0x04},
    

    【讨论】:

    • 它不起作用..写入文件它添加了这些字符,但在屏幕上打印时没有
    • @md.jamal 你不能 printf 控制代码(ASCII 代码 ^A 这样的输出。
    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2015-10-29
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2010-10-13
    • 2013-10-18
    • 1970-01-01
    相关资源
    最近更新 更多