2016-11-13 46 views
0

我有一個服務器客戶端應用程序,我正在開發基本上模擬聊天室。這是學校的一項任務,協議規範有些嚴格。如何將一個字符數組轉換爲uint8_t

我有一個字符數組,它將存儲來自客戶端的所有消息。

客戶端必須首先將消息的長度作爲uint8_t發送,然後將消息本身作爲char數組發送。

我的問題是我需要存儲發送實際消息之前發送的uint8_t值,但我只能使用消息數組來存儲來自客戶端的任何信息。

如果我沒有弄錯char數組將不會存儲發送的uint8_t,除非我以某種方式進行轉換。

如何將uint8_t轉換爲字符並返回到uint8_t?

我試過在這裏尋找類似的問題,但找不到示例。

server.c

char msg[100]; 
recv(clients_sd, msg, sizeof(msg), 0); 
uint8_t len; /* store the length of the message here */ 
char message_received[len]; 
recv(clients_sd, message_received, sizeof(message_received), 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, sizeof(clients_message), 0); 

回答

3

如果您使用的是體系結構,其中uint8_ttypedefunsigned char(你最有可能的是),後來乾脆拿第一char並將它投射到uint8_t

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

它應該工作。

+0

我會給你一個鏡頭。謝謝! – fatalError

0

字符可以很容易地轉換爲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, lentgth, 0); 
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' 

你需要小心的唯一的事情是,如果char帶有符號C標準沒有定義。與默認簽名的整數類型不同,如果您要求如此(例如,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%將被禁止。你知道你正在使用的平臺,並且你知道你的應用程序定位的平臺,所以你有責任確保代碼在所有這些平臺上都是正確的。

+0

uint8_t不能保證是字符類型的同義詞。因此,使用is來替代所有類型,因爲字符類型可能是不可移植的。 – 2501

+0

@ 2501請解釋「*除非系統中的字節不完全是8位(這樣的系統存在,但我打賭你從未使用過或甚至沒有看到過),uint8_t和char是完全相同的數據類型。 *「你完全不明白?除非你知道這個詞的意思嗎?請不要在我口中說出我從未說過的話。並且請不要評論你明顯沒有閱讀的答案。 – Mecki

+0

@ 2501一個'char'總是一個字節,C標準要求!如果一個字節在你的系統上有8位(**和我明確警告過這種情況不一定是這種情況!!! **),那麼'uint8_t'也是一個字節。請向全世界解釋一個字節不能是一個字節,因爲C標準還要求如果存在本地8位類型,「uint8_t」必須是該類型,如果「char」是8位,那麼這樣的本地類型必須存在。所以你的評論甚至沒有意義。 – Mecki

相關問題