将字符存储在字符指针中

时间:2015-09-07 09:12:43

标签: c string pointers

我有一个线程可以逐个解析出来的字符/字节。 我想将字节序列存储在一个字节指针中,最后当找到“\ 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}?
    }
}

2 个答案:

答案 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){              

这里没有错误,但有些事情必须清除:

    1. 您为bytes缓冲区分配内存了吗?也就是说,使用malloc()家庭功能?
    1. 如果是这样,你检查 malloc()返回并确保指针正常吗?
    1. 您是否包含stdbool.h以使用truefalse

继续......

byte = get();         
bytes = byte;          
*bytes++;
    1. 假设 get()返回unsigned char,因为您没有提供代码。
    1. 问题bytes = byte。您正在为unsigned char分配unsigned char *。这很糟糕,因为unsigned char *期待内存地址(又名指针)并且您正在给它一个字符(转换为一个非常糟糕的内存地址,导致您提供最多255个地址,而您的程序不允许访问),以及您的编译器当然抱怨关于那个任务......
    1. *byte++有两个"问题" (不是真正的问题):一个,你不需要*(取消引用)运算符来增加指针引用,你可以&# 39;已完成byte++; 两个,如果您将此行和前一行(bytes = byte)切换为*bytes++ = byte,则更短且更容易。如果您不知道此声明的作用,我建议您阅读operator precedenceassignment operators

然后我们......

if (byte == 'x'){      
    printf( "Your message: %s", bytes);
    bytes = NULL;      
}
    1. if没问题。
    1. printf()搞砸了,因为当你bytes这些字符时,你一直递增你的get()指针。这意味着bytes指向的当前位置是字符串的结尾(或消息)。要解决此问题,您可以执行以下两项操作之一: one ,对读取的字节数设置计数器,然后使用该计数器递减bytes指针并获得正确的地址;或两个,使用辅助辅助指针(我更喜欢它,因为它更容易理解)。
    1. bytes = NULL如果您对malloc()缓冲区执行了 bytes,那么您在此处销毁该引用,因为您正在进行有效更改指针指向 NULL 的地址。无论如何,清除缓冲区需要的是memset()。请在manual
    2. 中详细了解相关信息
    1. 另一个微妙的(但严重)问题是字符串字符的结尾,您忘记将其放入该字符串中。如果没有它,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);
        }
    }
    1. if ((*bytes++ = get()) == 'x')是三个byte = get(); *bytes++ = byte; if (byte == 'x')的复合版本。请参阅我告诉你的那个分配链接!这是一种简洁的写作方式,会让你在派对上看起来非常酷!
    1. *(bytes - 1) = 0x0; -1位用于排除保存在字符串中的x字符。只需一步,我们就会排除x 设置 NULL终止字节
    1. bytes = bytes_aux;这会恢复bytes默认状态 - 现在它正确指向消息的开头
    1. memset(bytes, 0, 500)我告诉你的重置字符串的功能。
    1. 此特定情况中不需要使用memset。每次循环重复我们都会从bytes缓冲区的开头向前保存字符。然后,我们设置一个NULL终止字节并恢复它的原始位置,有效地覆盖所有其他数据。 NULL 字节将负责阻止printf()打印当前消息结束后的任何谎言。因此可以跳过memset()部分并节省宝贵的CPU时间!
    1. 当你离开那个循环时(如果你这样做),请记住free() bytes指针!你不想要memory leaking...