Scinder la chaîne en tableau

Je me suis amusé avec la programmation pour Arduino, mais aujourd’hui, j’ai rencontré un problème que je ne peux pas résoudre avec ma connaissance très limitée du C. Voici comment ça se passe. Je crée une application PC qui envoie une entrée série à l’arduino (deviceID, command, commandparameters). Cet arduino transmettra cette commande par RF à d’autres arduino. Selon l’id du périphérique, l’arduino correct exécutera la commande.

Pour pouvoir déterminer le deviceID, je souhaite diviser cette chaîne en “,”. C’est mon problème, je sais comment le faire facilement en Java (même en n’utilisant pas la fonction split standard), cependant en C c’est une histoire totalement différente.

Est-ce que l’un de vous peut me dire comment faire fonctionner ça?

Merci

/* Serial Event example When new serial data arrives, this sketch adds it to a Ssortingng. When a newline is received, the loop prints the ssortingng and clears it. A good test for this is to try it with a GPS receiver that sends out NMEA 0183 sentences. Created 9 May 2011 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/SerialEvent */ Ssortingng inputSsortingng; // a ssortingng to hold incoming data boolean ssortingngComplete = false; // whether the ssortingng is complete Ssortingng[] receivedData; void setup() { // initialize serial: Serial.begin(9600); // reserve 200 bytes for the inputSsortingng: inputSsortingng.reserve(200); } void loop() { // print the ssortingng when a newline arrives: if (ssortingngComplete) { Serial.println(inputSsortingng); // clear the ssortingng: inputSsortingng = ""; ssortingngComplete = false; } } /* SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialEvent() { while (Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); if (inChar == '\n') { ssortingngComplete = true; } // add it to the inputSsortingng: if(ssortingngComplete == false) { inputSsortingng += inChar; } // if the incoming character is a newline, set a flag // so the main loop can do something about it: } } Ssortingng[] splitCommand(Ssortingng text, char splitChar) { int splitCount = countSplitCharacters(text, splitChar); Ssortingng returnValue[splitCount]; int index = -1; int index2; for(int i = 0; i < splitCount - 1; i++) { index = text.indexOf(splitChar, index + 1); index2 = text.indexOf(splitChar, index + 1); if(index2  -1) { index = text.indexOf(splitChar, index + 1); if(index > -1) returnValue+=1; } return returnValue; } 

J’ai décidé d’utiliser la fonction strtok . Je rencontre un autre problème maintenant. L’erreur s’est produite est

SerialEvent.cpp: Dans la fonction ‘void splitCommand (Ssortingng, char)’:

SerialEvent: 68: error: impossible de convertir ‘Ssortingng’ en ‘char *’ pour l’argument ‘1’ en ‘char * strtok (char *, const char *)’

SerialEvent: 68: erreur: ‘null’ n’a pas été déclaré dans cette étendue

Le code est comme,

 Ssortingng inputSsortingng; // a ssortingng to hold incoming data void splitCommand(Ssortingng text, char splitChar) { Ssortingng temp; int index = -1; int index2; for(temp = strtok(text, splitChar); temp; temp = strtok(null, splitChar)) { Serial.println(temp); } for(int i = 0; i < 3; i++) { Serial.println(command[i]); } } 

C’est une vieille question, mais j’ai créé un morceau de code qui peut aider:

  Ssortingng getValue(Ssortingng data, char separator, int index) { int found = 0; int strIndex[] = {0, -1}; int maxIndex = data.length()-1; for(int i=0; i<=maxIndex && found<=index; i++){ if(data.charAt(i)==separator || i==maxIndex){ found++; strIndex[0] = strIndex[1]+1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found>index ? data.subssortingng(strIndex[0], strIndex[1]) : ""; } 

Cette fonction renvoie une seule chaîne séparée par un caractère prédéfini à un index donné. Par exemple:

 Ssortingng split = "hi this is a split test"; Ssortingng word3 = getValue(split, ' ', 2); Serial.println(word3); 

Faut-il imprimer ‘est’. Vous pouvez également essayer avec l’index 0 renvoyant «hi» ou en toute sécurité, l’index 5 renvoyant «test».

J’espère que cette aide!

La mise en oeuvre:

 int sa[4], r=0, t=0; Ssortingng oneLine = "123;456;789;999;"; for (int i=0; i < oneLine.length(); i++) { if(oneLine.charAt(i) == ';') { sa[t] = oneLine.substring(r, i).toInt(); r=(i+1); t++; } } 

Résultat:

  // sa[0] = 123 // sa[1] = 456 // sa[2] = 789 // sa[3] = 999 

Pour l’allocation dynamic de mémoire, vous devrez utiliser malloc, à savoir:

 Ssortingng returnvalue[splitcount]; for(int i=0; i< splitcount; i++) { String returnvalue[i] = malloc(maxsizeofstring * sizeof(char)); } 

Vous aurez également besoin de la longueur maximale de la chaîne.

La méthode C pour fractionner une chaîne en fonction d’un délimiteur consiste à utiliser strtok (ou strtok_r ). Voir aussi cette question.

Je pense que votre idée est un bon sharepoint départ. Voici un code que j’utilise (pour parsingr les requêtes HTTP GET REST avec un bouclier Ethernet).

L’idée est d’utiliser une boucle while et lastIndexOf et de stocker les chaînes dans un tableau (mais vous pouvez faire autre chose).

“demande” est la chaîne que vous souhaitez parsingr (pour moi, cela s’appelait demande parce que … c’était).

  int goOn = 1; int count = -1; int pos1; int pos2 = request.length(); while( goOn == 1 ) { pos1 = request.lastIndexOf("/", pos2); pos2 = request.lastIndexOf("/", pos1 - 1); if( pos2 <= 0 ) goOn = 0; String tmp = request.substring(pos2 + 1, pos1); count++; params[count] = tmp; // Serial.println( params[count] ); if( goOn != 1) break; } // At the end you can know how many items the array will have: count + 1 ! 

J'ai utilisé ce code avec succès, mais je pense que c'est un problème d'encodage lorsque j'essaie d'imprimer params [x] ... je suis un débutant, donc je ne maîsortingse pas les caractères par rapport aux chaînes ...

J'espère que ça aide.