[英]how could i get int type value from char array?
我想從一個輸入文本中獲取三個不同的 int 值(我將輸入“nn_nn_n”)。
例如。 如果我輸入“60_25_5”,我的代碼通過使用下划線(_)並設置“null”將收到的文本分成三部分,我認為三個字符數組(text1、text2、text3)將具有每個值(60、25 , 5) 最后,為了將這些值用作 integer,我使用了 atoi()。
這是我的代碼:
#include <String.h>
#include <stdlib.h>
#include <SoftwareSerial.h>
void setup {
Serial.begin(9600);
Serial.println("start");
}
void loop() {
if(Serial.available()){
char *data = Serial.read();// = nn_nn_n
data[2]='\0';
data[5]='\0';
char *str ;
str = data ;
char text1[4];
strcpy(text1,str);
str = data + 3;
char text2[4];
strcpy(text2, str);
str = data + 6;
char text3[4];
strcpy(text3, str);
int a= atoi(text1);
int b= atoi(text2);
int c= atoi(text3);
Serial.print(a);
Serial.print(b);
Serial.print(c);
}
}
但結果是:
start
000000000000000000000000
我知道我是一個超級菜鳥,但我已經准備好學習你教我的東西,我等待你的評論。 謝謝。
如果您想教事情是如何工作的,請不要使用 arduino IDE,因為沒有很好的工具可以觀察 MCU 在做什么。 我使用 Atmel Studio 向您展示如何調試代碼的某些部分。 這是名為調試器(和模擬器)的工具,它允許查看整個 MCU 部件(查看附圖)。
基本上,您在代碼中存在三個基本誤解:
通過串行線路傳輸一個字符需要一些時間。 對於波特率 9600 波特,這次是10*1/baudRate
。 這大約是 1ms。
在此期間,MCU 能夠執行loop
function 可能數千次。 當然,大多數情況下什么都不做,因為Serial.available()
返回 false。 當傳輸消息的第一個字符到達時Serial.available()
返回 true 並且條件中的代碼開始執行。 但是整個代碼執行得非常快。 尚未傳輸其他字符。 下一個字符在 1ms 后再次到達。 所以你的代碼只處理一個字符,然后再次等待下一個到達的字符。 因為消息有 8 個字符(6 + CR LF),您的代碼八次寫入值變量ab c
並且您得到響應000 000 000 000 000 000 000 000
空間未發送,但它表示等待loop
ZC4F125264E67ZA8 中的下一個字符。 因此,在每個字符之后,MCU 接收到的打印值000
讓我們找出為什么所有變量都被評估為 0 值。
Serial.read()
未按預期返回字符串或字符串。 您必須閱讀 Arduino 文檔並理解它。 如果沒有可用數據或消息中的第一個可用字節,Function 返回-1
。 換句話說,你得到代表到達字符的 ASCII 值的數字。 在您的示例中,您得到第一個值 0x36,因為數字六的 ASCII 值是 0x36('6')。 這是原因,因為我將您的命令char *data = Serial.read();// = nn_nn_n
為char *data = '6';
代表第一個字符到達后的情況。
這個命令在做什么? (劇透 -在這種情況下非常糟糕)這個命令創建局部變量什么是指向 char 的指針。 此變量在堆棧上創建並占用兩個字節。 您可以在第一行的手表 window 中看到它。 你可以看到這個變量的地址是0x08E6
。 這個變量是在loop
function 中自動創建的,這里是調用Serial.read()
返回的插入值。 所以在第一個字符中有值0x36
。 但請記住,這是指向 char的指針,這意味着數據指針現在指向地址“0x36”。 這很糟糕,真的很糟糕。 地址0x36
上有什么。 您可以在 window Memmory1 中看到 MCU memory 的這一部分。 不幸的是,這是 memory 的一部分,保留用於訪問 IO 寄存器。 該寄存器控制 MCU 的硬件,如定時器、轉換器、SPI、IIC、UARTS……向該區域寫入隨機值是非常糟糕的主意。
data[2]='\0';
這將嘗試將零寫入0x0038
寄存器
data[5]='\0'
這將嘗試將零寫入0x003B
寄存器
在這種情況下,您很幸運,因為您可以看到這部分中的所有寄存器都為零值,並且您沒有破壞任何硬件配置。 所有其他命令都可以通過步進輕松檢查,並且很容易理解您仍然在玩機智的零長度字符串。 所以最終值變量ab c
變為零。
您可以考慮使用 strtok() 來解析數字。 然后仍然使用 atoi() 來獲取您的值。
看這個例子:
https://www.best-microcontroller-projects.com/arduino-strtok.html
void setup(void) {
char *token;
char *mystring = "apples,pears,bananas";
const char *delimiter =",";
Serial.begin(115200);
token = strtok(mystring, delimiter);
while (token != NULL) {
Serial.println(token);
token=strtok(NULL, delimiter);
}
}
void loop(void) {
}
只需使用標准庫:
#include <String.h>
#include <stdlib.h>
#include <SoftwareSerial.h>
#include <stdio.h>
void setup {
Serial.begin(9600);
Serial.println("start");
}
void loop() {
int a, b, c;
if(Serial.available()){
char* str = Serial.read(); // any in format of: "##_##_##", Ex: "60_25_5"
sscanf(text, "%d_%d_%d", &a, &b, &c);
printf("\nGiven numbers: %d, %d, %d", a, b, c);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.