简体   繁体   English

将字符存储在字符指针中

[英]store characters in character pointer

I have a thread which parses incomming characters/bytes one by one. 我有一个线程,一个接一个地解析传入的字符/字节。 I would like to store the sequence of bytes in a byte pointer, and in the end when the sequence of "\\r\\n" is found it should print the full message out. 我想将字节序列存储在字节指针中,最后,当找到“ \\ 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}?
    }
}

You should define bytes as array with size of max message length not a pointer. 您应该将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);
    }
}

When you define bytes as a pointer, it points to nothing and writing to it may erase other data in your program, you can make it array or allocate space for it in run time using malloc 当您将bytes定义为指针时,它不指向任何东西,对其进行写操作可能会擦除程序中的其他数据,您可以使用malloc将其设置为数组或在运行时为其分配空间

Your Code 您的密码

unsigned char byte;
unsigned char *bytes = NULL;

while (true){              

Nothing wrong here, but some things must be cleared: 这里没有问题 ,但必须清除一些事项:

    1. Did you alloc memory for your bytes buffer? 您是否为bytes缓冲区分配了内存 That is, using malloc() family functions? 也就是说,使用malloc()系列函数吗?
    1. If so, did you check malloc() return and made sure the pointer is ok? 如果是这样,您是否检查过 malloc()返回并确保指针正常?
    1. Did you include stdbool.h to use true and false ? 您是否包含stdbool.h来使用truefalse

Moving on... 继续...

byte = get();         
bytes = byte;          
*bytes++;
    1. I'm assuming get() returns an unsigned char , since you didn't give the code. 假设 get()返回一个unsigned char ,因为您没有给出代码。
    1. Problem : bytes = byte . 问题bytes = byte You're assigning an unsigned char to an unsigned char * . 您正在将unsigned char分配给unsigned char unsigned char * That's bad because unsigned char * is expecting a memory address (aka pointer ) and you're giving it a character (which translates into a really bad memory address , cause you're giving addresses up to 255, which your program isn't allowed to access), and your compiler certainly complained about that assignment... 这很糟糕,因为unsigned char *期望有一个内存地址 (又称指针 ),并且您给它一个字符 (这会转换成一个非常糟糕的内存地址 ,导致您要提供的地址最多为255,这是您的程序所不允许的)进行访问),并且您的编译器肯定抱怨该分配...
    1. *byte++ has two "problems" (not being really problems): one , you don't need the * (dereferencing) operator to just increment the pointer reference , you could've done byte++ ; *byte++有两个“问题”(不是真正的问题): 一个 ,您不需要* (解引用)运算符就可以增加指针引用 ,就可以做到byte++ two , it was shorter and easier to understand if you switched this line and the previous one ( bytes = byte ) to *bytes++ = byte . 第二 ,如果您将这一行和前一行( bytes = byte )切换为*bytes++ = byte则更容易理解。 If you don't know what this statement does, I suggest reading up on operator precedence and assignment operators . 如果您不知道该语句的作用,建议您阅读运算符优先级赋值运算符

Then we have... 那我们有...

if (byte == 'x'){      
    printf( "Your message: %s", bytes);
    bytes = NULL;      
}
    1. if 's alright. if还好。
    1. printf() is messed up because you've been incrementing your bytes pointer the whole time while you were get() ting those characters. printf()被弄乱了,因为在get()这些字符的整个过程中一直在增加 bytes指针。 This means that the current location pointed by bytes is the end of your string (or message ). 这意味着由bytes指向的当前位置是字符串 (或message )的末尾 To correct this, you can do one of two things: one , have a counter on the number of bytes read and then use that to decrement the bytes pointer and get the correct address; 要解决此问题,您可以执行以下两项操作之一: 一是在读取的字节数上设置一个计数器,然后使用该计数器减少bytes指针并获取正确的地址; or two , use a secondary auxiliary pointer (which I prefer, cause it's easier to understand). 两个 ,使用辅助辅助指针 (我更喜欢,因为它更容易理解)。
    1. bytes = NULL . bytes = NULL If you did malloc() for your bytes buffer, here you're destroying that reference, because you're making an assignment that effectively changes the address to which the pointer points to to NULL . 如果bytes缓冲区执行 malloc() ,则此处将销毁该引用,因为要进行赋值可以有效地将指针指向 的地址更改NULL Anyway, what you need to clear that buffer is memset() . 无论如何,您需要清除该缓冲区的是memset() Read more about it in the manual . 阅读手册中的更多内容。
    1. Another subtle (but serious) problem is the end of string character, which you forgot to put in that string altogether. 另一个细微 (但很严重)的问题是字符串字符的结尾 ,您忘记将其完全放在该字符串中。 Without it, printf() will start printing really weired things past your message until a Segmentation Fault or the like happens. 没有它, printf()将开始在消息之前打印真正奇怪的东西,直到出现Segmentation Fault之类的错误 To do that, you can use your already incremented bytes pointer and do *bytes = 0x0 or *bytes = '\\0' . 为此,您可以使用已经递增的 bytes指针,并执行*bytes = 0x0*bytes = '\\0' The NULL terminating byte is used in a string so that functions know where the string ends. 字符串中使用NULL终止字节 ,以便函数知道字符串的结尾。 Without it, it would be really hard to manipulate strings. 没有它,将很难操纵字符串。

Code

    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') is a compound version of the three byte = get(); *bytes++ = byte; if (byte == 'x') if ((*bytes++ = get()) == 'x')是三个byte = get(); *bytes++ = byte; if (byte == 'x')的复合版本byte = get(); *bytes++ = byte; if (byte == 'x') byte = get(); *bytes++ = byte; if (byte == 'x') byte = get(); *bytes++ = byte; if (byte == 'x') . byte = get(); *bytes++ = byte; if (byte == 'x') Refer to that assignment link I told you about! 请参阅我告诉过您的作业链接! This is a neat way of writing it and will make you look super cool at parties! 这是一种整齐的书写方式,会让您在聚会上看起来超酷!
    1. *(bytes - 1) = 0x0; The -1 bit is to exclude the x character which was saved in the string. -1位用于排除保存在字符串中的x字符。 With one step we exclude the x and set the NULL terminating byte . 第一步,排除x 设置NULL终止字节
    1. bytes = bytes_aux; This restores bytes default state - now it correctly points to the beginning of the message . 这将恢复bytes默认状态-现在它正确指向消息开头
    1. memset(bytes, 0, 500) The function I told you about to reset your string. memset(bytes, 0, 500)我告诉过您的有关重置字符串的函数。
    1. Using memset is not necessary in this particular case . 这种特殊情况下,不必使用memset Every loop repetition we're saving characters from the beginning of the bytes buffer forward. 每次循环重复,我们从bytes缓冲区的开始一直保存字符。 Then, we set a NULL terminating byte and restore it's original position, effectively overwriting all other data. 然后,我们设置一个NULL终止字节并恢复其原始位置,从而有效地覆盖所有其他数据。 The NULL byte will take care of preventing printf() from printing whatever lies after the end of the current message. NULL字节将防止printf()打印当前消息结束后的内容。 So the memset() part can be skipped and precious CPU time saved! 因此,可以跳过memset()部分并节省宝贵的CPU时间!
    1. Somewhere when you get out of that loop (if you do), remember to free() the bytes pointer! 当您离开该循环的某个位置时(如果这样做),请记住要free() bytes指针! You don't want that memory leaking... 您不希望内存泄漏...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM