为什么在字符数组的字符之间插入"\000"字符?

3

我正在尝试从UART读取流数据,并尝试将接收到的每个字符添加到char数组中,直到以这种顺序接收到字符\r\n

我编写了一个函数(char read_uart()),用于等待并返回单个字符。此函数正确接收并返回单个字符。

在此函数基础上,我尝试创建另一个函数,该函数应读取每个字符并将其添加到数组中,直到接收到终止组合。以下是它:

void read_full_uart(char *message[4096])
{
    char previousTwo[2] = {'\0', '\0'};
    for (uint16_t i = 0; !(previousTwo[0] == '\r' && previousTwo[1] == '\n'); i++)
    {
        char currentValue = read_uart();
        *(message + i) = currentValue;

        previousTwo[0] = previousTwo[1];
        previousTwo[1] = currentValue;
    }
}

这是我如何调用它:

char message[4096];
read_full_uart(&message);

然而,举例来说当传输 "比特币" 时,message 的内容如下所示: b\000\000\000i\000\000\000t\000\000\000c\000\000\000o\000\000\000i\000\000\000n\000\000\000\r\000\000\000\n\000\000\000 虽然字符被完好地接收,但是后面附加了三个 \000 字符。
我想知道为什么会这样,并且如何调整以避免插入这些额外字符。

2
你的函数期望得到一个包含4096个指向char的指针的数组(实际上是一个指向包含4096个指向char的指针的数组的指针)。但你传递了一个包含4096个char的数组。另外,*(message+i)=currentValue;message[i] = currentValue;是等价的,它们都将一个char赋值给了一个char*。你的编译器应该会对这些类型不匹配发出一些警告。 - Gerhardh
你是如何让 *(message + i) = currentValue; 编译通过的?你正在将一个 char (currentValue) 赋值给一个 char* (*(message+i))。 - Wyck
5
函数签名中的char *message[4096]很可能是一个错误。我的预测非常确定,你需要使用char message[4096],它与char message[]相同,在调用处进行相应的更改:read_full_uart(message)。此外,请务必始终使用所有警告启用(-Wall -Wextra在gcc中)编译您的代码,并将它们作为错误(-Werror)处理。 - SergeyA
1
@Wyck 可能会遇到著名的“从整数隐式地创建指针”的警告... - Gerhardh
3
专业提示:将警告视为错误处理。 - Wyck
1个回答

1

这里有两个问题。

首先,你传递给函数的不是它所期望的。 &message 的类型为 char (*)[4096],即大小为 4096 的 char 数组的指针。而函数期望的是一个 char *[4096],即大小为 4096 的 char * 数组。这是一种类型不匹配。

第二个问题出现在这一行:

*(message + i) = currentValue;

或者等价地说:

message[i] = currentValue;

你正在将一个char分配给类型为char *的数组。这也是一种类型不匹配。
编译器应该将这些问题作为警告捕捉到。如果没有,请通过传递选项-Wall -Wextra(假设使用gcc)来提高警告级别,并将警告视为错误。
您可以通过更改函数以接受char数组来修复这些错误:
void read_full_uart(char message[4096])

或等价地说:
void read_full_uart(char *message)

将数组直接传递到函数中:

read_full_uart(message);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接