极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 76883|回复: 24

arduino如何分割字符串

[复制链接]
发表于 2014-4-11 00:29:24 | 显示全部楼层 |阅读模式
RT 从串口读取一个数据例如11,22,33,44 如何将数据从逗号处分开 吧11 22 33 44分别丢到4个不同的变量里面并且转换成int型啊
#include <Stdio.h>
String comdata = "";
void setup()
{
Serial.begin(9600);
}
void loop()
{
  while (Serial.available() > 0)
  {
     comdata += char(Serial.read());
   delay(2);
}
Serial.print(comdata);  
Serial.println("");
if(Serial.available() > 0)
comdata = "";
}
回复

使用道具 举报

发表于 2014-4-11 02:16:26 | 显示全部楼层
我習慣自己 檢查輸入的 string, 不知是否有類似 split 的 function.

先設定數值為 0, 再由左至右不斷向每一個 字符 測試, 如果是數字, 就把原先的值 X 10 + 新的數字.  如果不是數字, 已又已經有數值, 就輸出一該數值, 然後 reset 為 0 再向後檢查直到完成整個 string.

回复 支持 反对

使用道具 举报

发表于 2014-4-11 08:57:51 | 显示全部楼层
char *strtok(char s[], const char *delim);
  1. char input[16] = "abc,d";
  2.     char *p;
  3.     /**/ /* strtok places a NULL terminator
  4.     in front of the token, if found */
  5.     p = strtok(input, ",");
  6.     if (p) printf("%s\n", p);
  7.     /**/ /* A second call to strtok using a NULL
  8.     as the first parameter returns a pointer
  9.     to the character following the token */
  10.     p = strtok(NULL, ",");
  11.     if (p) printf("%s\n", p);
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-11 10:05:26 | 显示全部楼层
Super169 发表于 2014-4-11 02:16
我習慣自己 檢查輸入的 string, 不知是否有類似 split 的 function.

先設定數值為 0, 再由左至右不斷向每 ...

根据你的思路写了这坨 但是打印t1的时候依旧没有内容
#include <Stdio.h>
String comdata = "";
int t1[6]={0};
int mark =0;
void setup()
{
Serial.begin(9600);
}
void loop()
{int j=0;
  while (Serial.available() > 0)
  {comdata += char(Serial.read());
   delay(2);
   mark = 1;
}
if(mark == 1)
{Serial.println(comdata);
for(int i = 0; i < comdata.length() ; i++)
{if(comdata == ',')
{j++;}
else
{t1[j]=t1[j]*10+(comdata-'0');
}
}
Serial.println(t1[6]);
}

//Serial.print(comdata);
//Serial.print(t1);  
//Serial.println("");
if(Serial.available() > 0)
comdata = "";
}
回复 支持 反对

使用道具 举报

发表于 2014-4-11 11:01:26 | 显示全部楼层
这样哪?你试试

  1. String comdata = "";
  2. int t1[6]={0};
  3. int mark =0,i=0;
  4. char *p=NULL;
  5. void setup()
  6. {
  7. Serial.begin(9600);
  8. }
  9. void loop()
  10. {
  11.   int j=0;
  12.   comdata="";
  13.   while (Serial.available() > 0)
  14.   {
  15.      comdata += char(Serial.read());
  16.      delay(2);
  17.      mark = 1;
  18.   }
  19.   if(mark == 1)
  20.   {
  21.     Serial.println(comdata);
  22.     p=strtok((char*)comdata.c_str(),",");
  23.     while(p)
  24.     {
  25.       t1[i]=atoi(p);
  26.       i++;
  27.       p=strtok(NULL,",");
  28.     }
  29.   }
  30.   for(int j=0;j<6;j++)
  31.   {
  32.     Serial.println(t1[j]);
  33.   }
  34. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2014-4-11 11:12:57 | 显示全部楼层
zerglingbug 发表于 2014-4-11 10:05
根据你的思路写了这坨 但是打印t1的时候依旧没有内容
#include
String comdata = "";

ching 對 integer array 好像有些地方攪錯了.

只用 Serial.println(t1[6]); 去顯示, 如果少於 7 個數, t1[6] 無資料是合理的.  
而且 int t1[6],  t1 只有 6 個空間 , t1[6] 會指向 t1 後的一個 資料, t1[6] 是無意義的.

Serial.print 不支援 integer array, 不可以直接列印整個 array, 要用 loop 去顯示:
for (int x=0; x < 6; x++) Serial.println(t1[x]);

回复 支持 反对

使用道具 举报

发表于 2014-4-11 11:14:44 | 显示全部楼层
最简单的办法是使用 Serial.parseInt() 函数。参考IDE里的例程 Read ASCII String
回复 支持 反对

使用道具 举报

发表于 2014-4-11 11:17:26 | 显示全部楼层
StringToIntRGB  这个例子中直接有你要的代码
几乎一模一样。
这样回答多省事情!!!
回复 支持 反对

使用道具 举报

发表于 2014-4-11 11:30:01 | 显示全部楼层
春泥蛋炒饭 发表于 2014-4-11 11:14
最简单的办法是使用 Serial.parseInt() 函数。参考IDE里的例程 Read ASCII String

Serial.parseInt 也是用同一方法做的, 不斷檢查 個別字符, 遇數字再 x10 + c - '0', 針對 Stream input 的.

自己拆可以一次過完成整個 input string, 並針對有關需要作出不同變化, 而且可以對一般 String (char*) 進行分折, 但就要自己做點功夫了.  

針對串口輸入, Serial.parseInt 確實會比較簡單一點.



回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-11 12:35:31 | 显示全部楼层
麽麽茶㊣ 发表于 2014-4-11 11:17
StringToIntRGB  这个例子中直接有你要的代码
几乎一模一样。
这样回答多省事情!!!

看了例程
又写了一坨 发现com口的数据如果不是直接存到string里 而是先存到int型 然后在放到string里的话 输出就不知道是啥玩意了。。。。
#include <Stdio.h>
String comdata1 = "";
String comdata2 = "";

void setup()
{
Serial.begin(9600);
}
void loop()
{int inChar;
  while (Serial.available() > 0)
  {
     inChar = char(Serial.read());
}
if (isDigit(inChar)) {
    comdata1 += (char)inChar;
}
Serial.print(comdata1);
回复 支持 反对

使用道具 举报

发表于 2014-4-11 13:27:36 | 显示全部楼层
available 是一个缓冲区
Serial.read提取出一个 他就少一个
在while里面直接  将缓冲区的东西提出完
String str += (char)Serial.read();
这就是你要的全部的字符串了。

你可以用mills函数 定时提取。也可以用停止符的方法提取。
“1,2,3#” 读到#  否则一直提取。在单片机里面用停止符的方法是最好的。

你是要思路还是直接代码? 思路理解完是你自己的东西。


回复 支持 反对

使用道具 举报

发表于 2014-4-11 14:12:07 | 显示全部楼层
zerglingbug 发表于 2014-4-11 12:35
看了例程
又写了一坨 发现com口的数据如果不是直接存到string里 而是先存到int型 然后在放到string里的话 ...

串口收到的資料, 本身沒有什麼類型的, 就是最基本的一個一個 byte 的.
它是什麼類, 是由你自己去決定的.

就像是 0x31 的一個 byte, 你說它是一個 整數, 就把它看成是 49 的數值去用; 你說它是 '1', 就把它當成是 '1' 去用.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-11 14:22:03 | 显示全部楼层
麽麽茶㊣ 发表于 2014-4-11 13:27
available 是一个缓冲区
Serial.read提取出一个 他就少一个
在while里面直接  将缓冲区的东西提出完

我的思路是这样子的 先用一个string类型+=char(Serial.read()); 这样就把串口发送的指令全部存到string类型里
然后再用一个char类型的数组 把string里面的东西扔到数组里面
最后在到数组里面一个一个字符判断 找到,就把剩下的字符写到第二个变量里面 否则就写进第一个变量里面
这样最后就能获得若干个char类型的数组 然后在转成int形式 就可以对元件进行控制了
回复 支持 反对

使用道具 举报

发表于 2014-4-11 14:29:40 | 显示全部楼层
你想的太多了。写代码前先排个草稿。既然要对元件控制还去考虑char数组干什么?直接int数组不就完了?
int led[XX]   int led[xx][xx] .....

下面写了一个  没试过。
  1. int led[3];
  2. void setup()
  3. {
  4.   Serial.begin(9600);
  5. }

  6. int currentColor = 0;
  7. int red, green, blue = 0;
  8. String str0 = "";
  9. void loop()
  10. {
  11.   boolean bRev = false;
  12.   
  13.   if(Serial.available()>0)
  14.   {
  15.     char c = (char)Serial.read();
  16.     if (c != '#')
  17.     {
  18.       str0 += c;
  19.     }
  20.     else
  21.     {
  22.       str0 += c;
  23.       bRev = true;
  24.     }
  25.   }
  26.   if(bRev)
  27.   {
  28.     String light = "";
  29.     int sLen = str0.length();
  30.     for(int j = 0; j < sLen; j++)
  31.     {
  32.       if(str0[j] == ',')
  33.       {
  34.         j++;
  35.         switch(currentColor)
  36.         {
  37.           case 0:
  38.             red = light.toInt();
  39.             led[0] = red;
  40.             light = "";
  41.             break;
  42.           case 1:
  43.             green = light.toInt();
  44.             led[1] = green;
  45.             light = "";
  46.             break;
  47.         }
  48.         currentColor++;
  49.       }
  50.       if(str0[j] == '#')break;
  51.       light += str0[j];
  52.     }
  53.     blue = light.toInt();
  54.     led[2] = blue;
  55.     light = "";
  56.     currentColor = 0;
  57.    
  58.     Serial.print(led[0]);
  59.     Serial.print('  ');
  60.     Serial.print(led[1]);
  61.     Serial.print('  ');
  62.     Serial.print(led[2]);
  63.     Serial.println("------------");
  64.   }
  65. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-11 14:50:21 | 显示全部楼层
麽麽茶㊣ 发表于 2014-4-11 14:29
你想的太多了。写代码前先排个草稿。既然要对元件控制还去考虑char数组干什么?直接int数组不就完了?
int ...

主要是int类型的话 我在com监视窗口不太好判断啊 搞了半天我已经接近成功了 已经能把com数据放到字符串里面并且判断逗号分割成两个量了。。现在就是不知道怎么分成3个量,循环想不出该咋写
#include <Stdio.h>
String comdata1 = "";
char t1[10];
void setup()
{
Serial.begin(9600);
}
void loop()
{int inChar;
  while (Serial.available() > 0)
  {
   comdata1 += char(Serial.read());
   delay(2);};
  for(int i=0;i<10;i++)
  {if (comdata1==',')
  break;
  t1=comdata1;}

Serial.print(comdata1);
Serial.print("//");
Serial.print(t1);
Serial.println("");
if(Serial.available() > 0)
comdata1="";
for(int i=0;i<10;i++)
t1='\0';
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-10 00:03 , Processed in 0.036217 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表