我有一个线程可以逐个解析出来的字符/字节。 我想将字节序列存储在一个字节指针中,最后当找到“\ r \ n”序列时,它应该打印完整的消息。
unsigned char byte;
unsigned char *bytes = NULL;
while (true){ // thread which is running on the side
byte = get(); // gets 1 byte from I/O
bytes = byte; //
*bytes++;
if (byte == 'x'){ // for now instead of "\r\n" i use the char 'x'
printf( "Your message: %s", bytes);
bytes = NULL; // or {0}?
}
}
答案 0 :(得分:1)
您应该将bytes
定义为最大消息长度大小而不是指针的数组。
unsigned char byte, i;
unsigned char arr[10]; // 10 for example
i=0;
while (true){
byte = get();
arr[i] = byte;
i++;
if (byte == 'x'){
printf( "Your message: %s", arr);
}
}
当您将bytes
定义为指针时,它指向任何内容并且写入它可能会删除程序中的其他数据,您可以使用malloc
在运行时为其创建数组或为其分配空间
答案 1 :(得分:0)
unsigned char byte;
unsigned char *bytes = NULL;
while (true){
这里没有错误,但有些事情必须清除:
bytes
缓冲区分配内存了吗?也就是说,使用malloc()
家庭功能?malloc()
返回并确保指针正常吗?stdbool.h
以使用true
和false
?继续......
byte = get();
bytes = byte;
*bytes++;
get()
返回unsigned char
,因为您没有提供代码。bytes = byte
。您正在为unsigned char
分配unsigned char *
。这很糟糕,因为unsigned char *
期待内存地址(又名指针)并且您正在给它一个字符(转换为一个非常糟糕的内存地址,导致您提供最多255个地址,而您的程序不允许访问),以及您的编译器当然抱怨关于那个任务...... *byte++
有两个"问题" (不是真正的问题):一个,你不需要*
(取消引用)运算符来增加指针引用,你可以&# 39;已完成byte++
; 两个,如果您将此行和前一行(bytes = byte
)切换为*bytes++ = byte
,则更短且更容易。如果您不知道此声明的作用,我建议您阅读operator precedence和assignment operators。然后我们......
if (byte == 'x'){
printf( "Your message: %s", bytes);
bytes = NULL;
}
if
没问题。printf()
搞砸了,因为当你bytes
这些字符时,你一直递增你的get()
指针。这意味着bytes
指向的当前位置是字符串的结尾(或消息)。要解决此问题,您可以执行以下两项操作之一: one ,对读取的字节数设置计数器,然后使用该计数器递减bytes
指针并获得正确的地址;或两个,使用辅助辅助指针(我更喜欢它,因为它更容易理解)。bytes = NULL
。 如果您对malloc()
缓冲区执行了 bytes
,那么您在此处销毁该引用,因为您正在进行有效更改指针指向 NULL 的地址。无论如何,清除缓冲区需要的是memset()
。请在manual。printf()
将开始打印超过您的消息的真实内容,直到Segmentation Fault或类似情况发生。为此,您可以使用已增加的 bytes
指针并执行*bytes = 0x0
或*bytes = '\0'
。 NULL终止字节用于字符串中,以便函数知道字符串结束的位置。没有它,操作字符串将非常难以 。 unsigned char byte;
unsigned char *bytes = NULL;
unsigned char *bytes_aux;
bytes = malloc(500);
if (!bytes) return;
bytes_aux = bytes;
while (true) { /* could use while(1)... */
byte = get();
*bytes++ = byte;
if (byte == 'x') {
*(bytes - 1) = 0x0;
bytes = bytes_aux;
printf("Your message: %s\n", bytes);
memset(bytes, 0, 500);
}
}
if ((*bytes++ = get()) == 'x')
是三个byte = get(); *bytes++ = byte; if (byte == 'x')
的复合版本。请参阅我告诉你的那个分配链接!这是一种简洁的写作方式,会让你在派对上看起来非常酷!*(bytes - 1) = 0x0;
-1
位用于排除保存在字符串中的x
字符。只需一步,我们就会排除x
和设置 NULL终止字节。 bytes = bytes_aux;
这会恢复bytes
默认状态 - 现在它正确指向消息的开头。memset(bytes, 0, 500)
我告诉你的重置字符串的功能。 memset
。每次循环重复我们都会从bytes
缓冲区的开头向前保存字符。然后,我们设置一个NULL终止字节并恢复它的原始位置,有效地覆盖所有其他数据。 NULL 字节将负责阻止printf()
打印当前消息结束后的任何谎言。因此可以跳过memset()
部分并节省宝贵的CPU时间!free()
bytes
指针!你不想要memory leaking...