如何将字符数组转换为uint8_t

时间:2016-11-13 23:19:09

标签: c casting send recv uint8t

我有一个我正在处理的服务器 - 客户端应用程序,它基本上模拟了一个聊天室。这是学校的一项任务,协议规范有些严格。

我有一个char数组,它将存储来自客户端的所有消息。

客户端必须首先将消息的长度作为uint8_t发送,然后将消息本身作为char数组发送。

我的问题是我需要存储在发送实际消息之前发送的uint8_t值,但我只能使用消息数组来存储来自客户端的任何信息。

如果我没弄错的话,char数组将不会存储被发送的uint8_t,除非我以某种方式投射它。

如何将uint8_t转换为字符并返回uint8_t?

我在这里尝试寻找类似的问题,但找不到一个例子。

server.c

uint8_t length = 21;
char clients_message[] = "Hi how are you today?";
send(servers_sd, &length, sizeof(length), 0);
send(serers_sd, &clients_message, sizeof(clients_message), 0);

client.c

#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
int main(){
    char s[20],*list[196][20];
    int i;
    FILE *lista;
    lista=fopen("lista.txt","r");
    i=0;
    while(feof==0){
        getline(list[i],0,lista);
        i=i+1;
        printf("%s\n",list[i]);
    }
    for(i=0;i<195;i++){
        //printf("%s\n",list[i]);
    }
    fclose(lista);
}

3 个答案:

答案 0 :(得分:3)

如果您使用uint8_ttypedefunsigned char(您很可能是)的架构,那么只需先取char并将其投放到uint8_t

length = (uint8_t)(message_received[0]);

它应该工作。

答案 1 :(得分:1)

char正好是一个字节(根据C标准的定义)。除非字节在您的系统上不是8位(这样的系统存在,但我敢打赌,您从未使用过或甚至没有使用过),uint8_tchar的数据类型完全相同。

char c = 5;
uint8_t u = c;

如果您可以使用数据类型执行类似的操作,那么您可以根据需要在这两种数据类型之间转换指针:

 char c[] = { 'H', 'e', 'l', 'l', 'o' };
 uint8_t * u = (uint8_t *)c;
 uint8_t x = u[1];
 // x is 101, which is the ASCII char code of 'e'

实际上你甚至可以用字符串来做,因为字符串也只是一个字符数组,只有一个NUL终止。

 char * c = "Hello"; 
 // "Hello" is in fact just { 'H', 'e', 'l', 'l', 'o', '\0' }
 uint8_t * u = (uint8_t *)c;
 uint8_t x = u[1];
 // x is 101, which is the ASCII char code of 'e'

唯一需要注意的是C标准没有定义char是签名还是未签名。与默认情况下签名的整数类型不同,如果您请求的话,只有无符号整数类型(例如long vs unsigned long),默认情况下char可能是有符号或无符号的。因此,如果您需要其中任何一个,则必须使用signed charunsigned char作为数据类型。在实践中,除非您对char值执行某些数学或逻辑运算(在现代C代码中您可能不应该这样做),否则它不起作用。

由于你的消息不可能大于256个字符(否则长度不适合uint8_t)并且长度总是恰好一个字节,我会编写如下代码:

uint8_t messageLength = 0;
ssize_t bytesRead = recv(clients_sd, &messageLength, 1, 0);
if (bytesRead == -1) {
     // Handle read error
}
if (bytesRead == 0) {
     // Handle end of stream
}

char message[256];
bytesRead = recv(clients_sd, message, messageLength, 0);
if (bytesRead == -1) {
     // Handle read error
}
if (bytesRead == 0) {
     // Handle end of stream
}
if (bytesRead < messageLength) {
     // Handle truncated message (message too small)
}

再一次,显然有些人已经不理解我的第二句了:我在假设之上写的所有东西,系统上的字节都是8位长。这段代码不能移植到字节多于或少于8位的平台,这已经是我的第二句明确指出的,但这并没有使我的回复错误。如果不允许编写不可移植到地球上所有现有平台的C代码,则将禁止所有现有C代码的90%。您知道您正在使用的平台,并且您知道您使用应用程序定位的平台,因此您有责任确保所有这些平台的代码都正确。

答案 2 :(得分:0)

char可以很容易地转换为uint8_t,但我不明白你为什么需要在消息数组中存储长度。为什么不能只存储在变量中?

这里是您的客户端和服务器示例,我认为这些更改很有帮助:

server.c

uint8_t len; /* store the length of the message here */
recv(clients_sd, &len, sizeof(len), 0);    
char message_received[len];
recv(clients_sd, message_received, len, 0); /* get and store the message here */

client.c

uint8_t length = 21;
char clients_message[] = "Hi how are you today?";
send(servers_sd, &length, sizeof(length), 0);
send(serers_sd, clients_message, length, 0);