2009-12-05 4 views
2

J'essaie de manipuler une chaîne en C++. Je travaille avec une carte Arduino donc je suis limité sur ce que je peux utiliser. Je suis encore en train d'apprendre C++ (Désolé pour toutes les questions stupides)Manipulation de chaînes en utilisant Arduino et C++

Voici ce que j'ai besoin de faire: Je dois envoyer des miles par heure à un affichage à 7 segments. Donc, si j'ai un numéro tel que 17.812345, j'ai besoin d'afficher 17.8 à l'affichage à 7 segments. Ce qui semble être le moyen le plus efficace est de multiplier d'abord par 10 (Ceci est de décaler le point décimal juste à un endroit), puis de lancer 178.12345 à un int (pour couper les points décimaux). La partie sur laquelle je suis coincé est la façon de se séparer 178. En Python, je pourrais découper la chaîne, mais je ne trouve rien sur la façon de faire cela en C++ (ou du moins, je ne trouve pas les bons termes pour chercher pour)

Il existe quatre affichages à 7 segments et un contrôleur d'affichage à 7 segments. Il va mesurer jusqu'à dixièmes de mile par heure. Merci beaucoup pour votre aide et les informations que vous pouvez me fournir.

+0

Merci beaucoup pour votre information et votre aide. Je l'apprécie vraiment – Dan

+0

@Dan Si vous avez une réponse qui a résolu votre problème Arduino, s'il vous plaît laissez-nous savoir lequel en appuyant sur la coche verte. Par conséquent, d'autres personnes avec le même problème Ardunio savent ce qu'il faut essayer en premier. –

Répondre

10

Il serait probablement plus facile de ne pas le convertir en une chaîne, mais il suffit d'utiliser l'arithmétique pour séparer les chiffres, à savoir

float speed = 17.812345; 
int display_speed = speed * 10 + 0.5;  // round to nearest 0.1 == 178 
int digits[4]; 
digits[3] = display_speed % 10;   // == 8 
digits[2] = (display_speed/10) % 10; // == 7 
digits[1] = (display_speed/100) % 10; // == 1 
digits[0] = (display_speed/1000) % 10; // == 0 

et, comme l'a souligné dans les commentaires, si vous avez besoin de la valeur ASCII chaque chiffre:

char ascii_digits[4]; 
ascii_digits[0] = digits[0] + '0'; 
ascii_digits[1] = digits[1] + '0'; 
ascii_digits[2] = digits[2] + '0'; 
ascii_digits[3] = digits[3] + '0'; 
+0

Et bien sûr, il est trivial de prendre les éléments individuels de chiffres et d'obtenir le code ASCII s'il en a réellement besoin. – imaginaryboy

4

Cette façon vous pouvez le faire en C++ sans mathématiques module (de toute façon me semble bien à):

#include "math.h" 
#include <stdio.h> 
#include <iostream.h> 

int main() { 

     float value = 3.1415; 
     char buf[16]; 
     value = floor(value * 10.0f)/10.0f; 
     sprintf(buf, "%0.1f", value); 

     std::cout << "Value: " << value << std::endl; 

     return 0; 
} 
+2

'buf' devrait être plus grand que 4, car même" 17.8 "ne laisse aucune place au terminateur nul. – cobbal

+0

Bon point cobbal - Vous m'avez rattrapé en essayant de trop optimiser, en rouge. 2^4 devrait suffire :) –

2

Si vous voulez réellement traiter ce genre de choses comme des chaînes, je vous recommande de regarder dans stringstream. Il peut être utilisé de la même manière que n'importe quel autre flux, tel que cin et cout, sauf qu'au lieu d'envoyer toutes les sorties vers la console, vous obtenez un string réel de la transaction.

Cela fonctionnera avec C++ standard. Je ne sais pas grand-chose sur Arduino, mais quelques recherches rapides suggèrent qu'il ne supportera pas les strings.

Un exemple rapide:

#include <sstream> // include this for stringstreams 
#include <iostream> 
#include <string> 

using namespace std; // stringstream, like almost everything, is in std 

string stringifyFloat(float f) { 
    stringstream ss; 
    ss.precision(1); // set decimal precision to one digit. 
    ss << fixed;  // use fixed rather than scientific notation. 
    ss << f;   // read in the value of f 
    return ss.str(); // return the string associated with the stream. 
} 

int main() { 
    cout << stringifyFloat(17.812345) << endl; // 17.8 
    return 0; 
} 
0

Vous pouvez utiliser une fonction telle que cette toString et travailler votre chemin à partir de là, comme vous le feriez en Python, ou tout simplement utiliser modulo 10,100,1000, etc pour l'obtenir en tant que nombres. Je pense que le manipuler comme une chaîne pourrait être plus facile pour vous, mais c'est à vous.

Vous pouvez également utiliser boost::lexical_cast, mais il sera probablement difficile de faire fonctionner votre système dans un système embarqué comme le vôtre.

0

Une bonne idée serait de mettre en œuvre un flux pour l'affichage. De cette façon, la syntaxe du flux C++ pourrait être utilisée et le reste de l'application resterait générique. Bien que cela puisse être excessif pour un système intégré.

Si vous souhaitez toujours utiliser std::string, vous pouvez utiliser un itérateur inversé. De cette façon, vous pouvez commencer par le chiffre le plus à droite (dans la chaîne) et de travailler vers la gauche, un caractère à la fois.

Si vous avez accès au code de la bibliothèque d'exécution, vous pouvez configurer une E/S en langage C pour l'affichage. C'est plus facile à implémenter qu'un flux C++.Vous pouvez ensuite utiliser fprint, fputs pour écrire sur l'affichage. J'ai implémenté un port de débogage dans cette méthode, et il était plus facile pour le reste des développeurs d'utiliser.