PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit itoa()



Spurius
11.10.2005, 10:08
Hallo,
warum wird beim folgenden Code die 100 nicht richtig übertragen?


int main(void)
{
DDRB = (1<<DDB0);
PORTB = (0<<PB0);
init_servo();
init_usart();
sei();
for(;;)
{
char *test;
char *test2;
test = "erfolg!!!";
send_string(test);
itoa(100,test2,10); // <<<---
send_string(test2);
waitms(1000);
}
}

"erfolg" wird eigentlich richtig übertragen, aber vllt mache ich das mit den pointern ja falsch, ich bin in c noch nicht so versiert.
Gruß
Martin

millioneer
11.10.2005, 11:00
test2 ist in deiner Definition erstmal nur ein Pointer auf ein Feld von Zeichen auch bekannt als String. Dem musst du noch Speicher reservieren oder du definierst das als char test2[10], dann ist das auch ein String aber der hat schon Speicher für 10 Zeichen bekommen ohne konkreten Inhalt.

Kjion
11.10.2005, 13:23
Hi,

so sollte das schon eher funktionieren:



int main(void)
{
DDRB = (1<<DDB0);
PORTB = (0<<PB0);
init_servo();
init_usart();
sei();
for(;;)
{
char test[] = "erfolg!!!";
char test2[3];
char *p_test = test;
char *p_test2 = test2;
send_string(p_test);
itoa(100,p_test2,10);
send_string(p_test2);
waitms(1000);
}
}

MfG Kjion

SprinterSB
11.10.2005, 14:14
test2 hat keinen vernünftigen Wert, es zeigt irgendwo hin.

char test2[***];
oder
static char test2[***];

Spurius
11.10.2005, 15:39
Hallo,
also so wirklich hab ich das noch nciht verstanden:


for(;;)
{

char test[] = "erfolg!!!";
char *p_test = test; //p_test zeigt auf den inhalt von test
*p_test = "bongo";
send_string(p_test);
char test2[] = "hallo\n\r";
char *p_test2 = test2;
send_string(p_test2);
waitms(1000);
}

Eigentlich würde ich jetzt "bongohallo" erwarten, ich bekomme jedoch
"jerfolg!!!hallo".

SprinterSB
11.10.2005, 15:51
Hallo,
also so wirklich hab ich das noch nciht verstanden:


for(;;)
{
// Hiwer wird test[] initialisiert, inefizient, aber ok...
char test[] = "erfolg!!!";
// ok
char *p_test = test; //p_test zeigt auf den inhalt von test
// Öhm...hier wird test[0] mit der Adresse von "bongo", als char gecastet, überschrieben. Strings werden kopiert mit strcpy() oder strncpy()
*p_test = "bongo";
send_string(p_test);
char test2[] = "hallo\n\r";
char *p_test2 = test2;
send_string(p_test2);
waitms(1000);
}

Eigentlich würde ich jetzt "bongohallo" erwarten, ich bekomme jedoch
"jerfolg!!!hallo".

Nö , das ist ok ;-)

Spurius
11.10.2005, 16:03
??, wie soll ich das verstehen? Ist die nichtgewollte Ausgabe auf den Code zurückzuführen oder ist der Code richtig und die Ausgabe unerklärlich?
Was muss ich da denn verändern?

SprinterSB
11.10.2005, 16:16
Hab ich doch ober erklärt... im Code.

*p_test ist das erste Zeichen des Strings.

*p_test = 'X' ist also gleichbedeutend mit p_test[0] = 'X'

String ist ja kein C-Typ, sondern nur char. Indem du dir die Adresse eines Strings besorgst und diese kopierst, hast du noch nicht den String kopiert. Hatte ich auch obern geschrieben...

Spurius
11.10.2005, 16:26
Hi,
sry, hatte oben gedacht du zitierst mich bloss und mir das nicht mehr näher angeschaut.

SprinterSB
11.10.2005, 16:51
Jo, war wohl ungeschickt da zu annotieren.

Wenn du so was machst wie

blah()
{
char str1[] = "...";
}

Dann ist das nicht sonderlich effizient. Die Variable wird erst bei der Benutzung initialisiert, also ist das langsam.

Besser ist dann schon so was wie

blah()
{
static char str1[] = "...";
}

Hier wird beim Verwenden nur die Anfangsadresse des Strings zugewiesen, die eigentliche Initialisierung erfolt im Startup-Code aus der crt*.o

Für unveränderliche Strings ist das auch nicht so toll, weil das sowohl Platz im RAM (da lebt der String) und im Flash (von da aus wird er initialisiert) belegt.

Besser lässt man des String im Flash. Da AVRs aber eine Harvard-Architektur haben, kann man anhand der Adresse des Strings nicht mehr entsceiden, woher er kommt. Das allerdings muss man zur korrekten Behandlung wissen.

Du bräuchtest dann neben uart_send_string(char*) eine uart_send_string_P (prog_char*)


#include <avr/pgmspace.h>

void uart_send_char (const char);

void uart_send_string_P (const prog_char* pstr)
{
while (1)
{
char c = (char) pgm_read_byte (pstr);
if ('\0' == c)
break;
pstr++;
uart_send_char (c);
}
}

// Lokatiert den String ins Flash
const prog_char str2[] = "...";
//oder
const char str3[] PROGMEM = "...";

blah()
{
uart_send_string_P (str2);
// Schneller geschrieben ist folgendes, aber schlechter,
// wenn öfter der gleiche String ausgegeben werden soll
uart_send_string_P (PSTR ("..."));
}