C Zahlvariablen in char* umwandeln?

R

Robert Alpha

Gast
Hallo Leute,
ich versuche grade für einen Mikrocontroller ein Programm zu schreiben, bei dem ich eine Zahl hochzähle, und diese auf einem Display ausgebe.
Zur Ausgabe auf dem Display verwende ich eine bereits vorhandene Routine.
Das Problem ist, die Zahlen sind integer- Typen, die Display- Routine benötigt allerdings char*- Variablen, oder Text in Anführungszeichen.

Ich hab schon alles versucht, die Zahlen in ein Array zu schreiben, also z.b. 144 wird [0 1 4 4], aber das ist ja auch noch kein Zeigertyp, weshalb das Display noch immer nichts anzeigt. :(

Gibt es vielleicht doch Möglichkeiten, die Zahlen umzuwandeln, oder vielleicht in der Art: "__Zahl__" in die Anführungszeichen zu schreiben?

Ich hoffe ihr habt ein paar Ideen!

mfg
 
Um einen Integer Wert in einen char umzuwandeln brauchste nur den entsprechenden ASCII Code für die Zahl zu verwenden:

ASCII: char
48: '0'
49: '1'
...
57: '9'
 
Hallo,

also zunächst einmal: ein Array ist in C auch ein Zeigertyp. Eine Funktion display(const char *s) ist also auch so aufrufbar:

char ca[5] = "0123";
display(ca);

Was du auch probieren könntest, wäre die Methode itoa() (integer to ascii), die je nach C-Bibliothek vorhanden sein kann oder auch nicht (stdlib.h einbinden!).

Falls das alles nicht geht, musst du die Zahl selbst umwandeln (durch wiederholte Division durch 10 und auffangen des Divisionsrests, also Modulo).

Melde dich nochmal, wenn du Hilfe brauchst.

Gruß,
tomcat83
 
Danke schon mal für die Antworten!

@tomcat83: Die erste Umwandlung funktioniert wenigstens mal, aber darstellen über cout kann ich das auch nicht (kanns momentan nich am µ-C testen)
Die itao - Funktion meckert auch rum, da haperts an einer initializer expression list :confused_alt:
Code:
#include <iostream>
#include <stdlib.h>
using namespace std;

main()
{
    int zahl = 1;
    char* text;
    char* itoa (zahl, text);
    cout << text;
}

Mit Modulo hab ichs zu Beginn schon versucht, aber eben in char alleine, die Funktionen werd ich nachher mal testen, wenn ich an den Controller komme, aber irgendwie hab ich das Gefühl, der will mich verschaukeln -.-
 
itoa ist keine standard funktion. Es kann sein, dass es die bei deinem µ-C gar nicht gibt. Warum verwendest du nicht einfach sprintf? Das ist dafür da und ist Standardkonform.
 
Jo, danke für den Tipp DjNDB! :daumen:

Jetzt schlage ich mich damit rum :D
Am Beispiel von der Seite:
Example

/* sprintf example */
#include <stdio.h>

int main ()
{
char buffer [50];
int n, a=5, b=3;
n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
printf ("[%s] is a %d char long string\n",buffer,n);
return 0;
}


Output:
[5 plus 3 is 8] is a 13 char long string
Welchem Text entspricht hier %d und weiter unten %s?

Und gibt es einen Grund, warum ich gerade hier das i nicht verwenden kann? (Screen)
 

Anhänge

  • sprintf.JPG
    sprintf.JPG
    29,7 KB · Aufrufe: 1.424
Zuletzt bearbeitet:
Robert Alpha schrieb:
Welchem Text entspricht hier %d und weiter unten %s?

Und gibt es einen Grund, warum ich gerade hier das i nicht verwenden kann? (Screen)

Steht doch alles in der Dokumentation. %d und %s sind Platzhalter für Integer bzw. String.

Ich weiß nicht was du mit dem i meinst. Wie lautet denn die genaue Warnung oder Fehlermeldung?
 
als parameter musst du Adressen übergeben ;)

versuchs mal mit sprintf(text, "Zeit = %d", &time);
 
Variablen deklariert man am Anfang der Funktion. Denke nicht, dass man das in einer For-Schleife tun kann.
Auch deklarierst du sie dann ja mit jedem Schleifendurchlauf neu, was wohl kaum das ist, was du willst.
Welchen Sinn haben die Variablen a und time? Und printf(variable) ist sehr sehr falsch. Und warum returnst
du innerhalb der Schleife? Die kann ja dann eh nur einmal durchlaufen werden und ist deshalb überflüssig.

€: Semikolon hinter for() nicht gesehen. Aber warum das? Wofür dann die geschweiften Klammern, bei denen
man erstmal denkt, das käme in die Schleife? Wofür ist die Schleife dann überhaupt da?
Warum machst du es nicht irgendwie so?

Code:
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i;
    char text[50];
    for(i = 0; i < 100; i++) {
        sprintf(text, "Time = %d\n", i);
        <Was auch immer du mit dem char* tun willst>
    }
    return EXIT_SUCCESS;
}

als parameter musst du Adressen übergeben

versuchs mal mit sprintf(text, "Zeit = %d", &time);
Nein, muss er nicht.
 
Zuletzt bearbeitet:
@asdfman: Ups, das Semikolon hab ich gar nich gesehn!

Und jetzt funktioniert der Timer, hab das sprintf benutzt! Danke! :)
 
Zwar schreibst du im Threadtitel, du wärst an einer C-Lösung interessiert, an deinem Codebeispiel wird dann aber deutlich, daß du eigentlich mit C++ arbeitest. Der für C++ idiomatischste Ansatz, Zahlen in Zeichenketten zu schreiben, ist folgender:

Code:
#include <sstream>
#include <string>

int main()
{
	const int irgendEineZahl = 3442426;
	
	// Einen string-stream anlegen. String streams werden benutzt, um Zahlen und andere Dinge in Zeichenketten zu schreiben.
	std::ostringstream einStream;
	
	// Zahl in den Stream schreiben.
	einStream << irgendEineZahl;
	
	// Jetzt den String aus dem Stream holen.
	const std::string derFertigeString = einStream.str();
	
	// Wenn du jetzt eine Funktion hast, die keinen std::string sondern einen const char* erwartet, kommst du an
	// den Inhalt des std::string-Objektes wie folgt ran.
	funktionDieConstCharPointerWill( derFertigeString.c_str() );
}
 
Ja stimmt schon, wir lernen jetzt C++, aber der Mikrocontroller will Assembler oder C -.-
Aber so groß sind die Unterschiede ja nicht.

So wie du das jetzt schreibst, erscheint mir das nach der alten Schreibweise, oder? Ohne namespace usw.?

Erstellt die Funktion .c_str() einen Zeiger oder gaukelt die nur den Inhalt vor?
 
@Robert Alpha Schau mal, ob die C-Lib deines mC "snprintf" dabei hat.

snprintf ist sprintf eigentlich immer vorzuziehen, damit man nicht irgendwann zufällig in einen Bufferoverflow rennt.

Der Unterschied in der Syntax ist, dass du die Größe des char-Buffers mitangeben musst, also:
snprintf(buffer,buffer_size,format,...)
Ergänzung ()

Robert Alpha schrieb:
Ja stimmt schon, wir lernen jetzt C++, aber der Mikrocontroller will Assembler oder C -.-
Aber so groß sind die Unterschiede ja nicht.
Außer dass du einen C++-Compiler brauchst. ;-) Aber den gibt es für die meisten mC.

Robert Alpha schrieb:
So wie du das jetzt schreibst, erscheint mir das nach der alten Schreibweise, oder? Ohne namespace usw.?
Das was antred schrieb ist doch mit Namespaces und sieht auch sonst richtig aus.
Robert Alpha schrieb:
Erstellt die Funktion .c_str() einen Zeiger oder gaukelt die nur den Inhalt vor?
c_str() ist normalerweise ein const Zeiger auf die Daten im std::string selber. (Viel anders lässt sich der Standard eigentlich auch nicht erfüllen...). Das, was c_str() zurückgibt, darf man daher niemals von Hand löschen und man sollte auch vermeiden nach der Zerstörung des std::strings darauf zuzugreifen.
 
Robert Alpha schrieb:
Ja stimmt schon, wir lernen jetzt C++, aber der Mikrocontroller will Assembler oder C -.-
Aber so groß sind die Unterschiede ja nicht.

Hmm, naja, das hängt ganz davon ab, ob man sich nur auf eine C-ähnliche Untermenge von C++ beschränkt, oder ob man so richtig in die vollen langt und alles auszeizt, was C++ so hergibt. ;)

Modernes C++ (also nicht der altertümliche, uninspirierte Quark, der heute meist an Unis gelehrt wird) mit Templates, der C++ Standard-Bibliothek und den Boost Libraries ( http://www.boost.org/ ) oder ähnlichen Libraries unterscheidet sich schon enorm stark von C.
Ergänzung ()

Robert Alpha schrieb:
So wie du das jetzt schreibst, erscheint mir das nach der alten Schreibweise, oder? Ohne namespace usw.?

Nö. Schau mal auf den std:: Präfix, den ich string und ostringstream spendiert habe. Die Sachen liegen nämlich alles im Namespace std. Alternativ hätte man auch einmal using namespace std; schreiben können ... dann hätte man sich den std:: Präfix später sparen können.

Robert Alpha schrieb:
Erstellt die Funktion .c_str() einen Zeiger oder gaukelt die nur den Inhalt vor?

.c_str() gibt lediglich einen Zeiger zurück, der auf ein internes Character-Array des String-Objektes zeigt. Anders geht es auch nicht. Würde die Funktion eine Kopie der Zeichenkette anlegen und dir dann einen Zeiger auf diese Kopie zurückgeben, dann wärst du dafür verantwortlich, diese Kopie später mit delete [] abzuräumen. Das stünde im Gegensatz zur Philosophie von Objekten in C++ (jeder räumt seinen Dreck selber wieder weg). :)
 
Zuletzt bearbeitet:
Zurück
Oben