Hallo,
ich komme nicht weiter. Ich will ein LCD Display ansteuern. Es soll
einen string anzeigen. Die Länge wird richtig erkannt aber der Inhalt
ist Blödsinn.
Ich rufe die routine im main.c so auf:
1
unsignedcharCHAR[20];
2
strcpy(CHAR,"HALLO");
3
lcd_display_string(*CHAR);
Das unterprogramm geht so:
1
voidlcd_display_string(char*STR)
2
{
3
uint8_ti;
4
unsignedcharnew_CHAR;
5
unsignedcharu_CHAR;
6
for(i=0;i<strlen(STR);i++)
7
{
8
new_CHAR=*(STR+1);
9
if(new_CHAR)
10
{
11
u_CHAR=(unsignedchar)new_CHAR;
12
lcd_send_data(u_CHAR);
13
}
14
}
15
}
einzelne char mit lcd_send_data(u_CHAR); geht aber
kann mir jemand sagen was falsch ist
Vielen Dank im Voraus
Ralph
man kann es aber auch kompliziert machen ...
Und variablen CHAR zu nennen, ist auch nicht gerade sinnvoll
unsigned char s[20];
strcpy( s, "HALLO" );
lcd_display_string(s);
void lcd_display_string(char *s)
{
while(*s) {
lcd_send_data( *s );
s++;
}
}
Durch den * beim *CHAR bekommst du nur das 'H'.
Was lcd_display_string aber als Adresse interpretiert.
Ergebnis ist Müll.
Sollte aber auch der Compiler anmeckern (als Warnung).
Für Zeichen nimmt man char.
Beim rechnen mit kleinen Integerbereichen nimmt man dann signed char
oder unsigned char
Vielen Dank für eure schnelle Antwort und den bereinigten code.
Allerdings zeigt es immer noch nicht das an was es soll. Es kommt irgend
ein komisches Zeichen, könnte fast arabisch sein. Es ist für "Hallo" 5
mal genau das gleiche hintereinander. Nehme ich einen anderen String,
kommt ein anderes Zeichen aber wieder mit der richtigen Anzahl der
Stellen das Gleiche hintereinander. Es scheint als ob der pointer nicht
weiter zählt und das ASCII Zeichen falsch interpretiert wird.
?????
Ich danke Euch schon mal
Ralph
Peter II schrieb:> while(*s) {> lcd_send_data( *s );> s++;> }> }
Und was ist wenn jetzt das Array warum auch immer kein \0 enthält, z.B.
weil das Array so befüllt wurde?
s[0] = 'H';
s[1] = 'A';
s[2] = 'L';
s[3] = 'L';
s[4] = 'O';
Dann werden solange Zeichen ausgegeben, bis eine 0 auftaucht (oder bis
zur Unendlichkeit und noch viel weiter).
Es kann auch einen Speicherzugriffsfehler geben, wenn das System das
unterstützt.
Da die Zeichenfolge kein C-String ist, musst du die Länge auf andere
Weise weiter geben.
Dann funktioniert strlen() aber auch nicht mehr.
Vilex schrieb:> Und was ist wenn jetzt das Array warum auch immer kein \0 enthältDirk B. schrieb:> Dann werden solange Zeichen ausgegeben, bis eine 0 auftaucht (oder bis> zur Unendlichkeit und noch viel weiter).> Es kann auch einen Speicherzugriffsfehler geben, wenn das System das> unterstützt.
Wer eine "Funktion" falsch benutzt, muss sich nicht wundern, wenn nicht
das erwartete raus kommt...
Was ich sagen will:
feu schrieb:> Es soll einen string anzeigen
Der TO redet von einem String, also muss der TO auch dafür sorgen das es
ein String (im entferntesten sinne) ist, und mit einer '\0'
abgeschlossen ist.
Vilex schrieb:> z.B.> weil das Array so befüllt wurde?> s[0] = 'H';> s[1] = 'A';> s[2] = 'L';> s[3] = 'L';> s[4] = 'O';
Jedes Element des Arrays mit '\0' initialisieren und erst dann befüllen
könnte helfen. Wenn man natürlich alle elemte belegt, also kein Platz
mehr für ein '\0' ist, dann hat man was falsch gemacht, denn dann dürfte
die Version mit
feu schrieb:> strcpy( CHAR, "HALLO" );
auch nicht mehr funktionieren, weil kein '\0' ins Array geschrieben
wird. Man sollte halt ganz grob wissen, was man da tut ;)
Grüße
Vilex schrieb:> Peter II schrieb:>> while(*s) {>> lcd_send_data( *s );>> s++;>> }>> }>> Und was ist wenn jetzt das Array warum auch immer kein \0 enthält
Dann hat man auch keinen String im C-Sinne und sollte tunlichst keine
String-Funktionen benutzen.
Man muss halt wissen was man tut. Ansonsten sollte man das Programmieren
bleiben lassen und lieber im Sandkasten spielen.
Karl Heinz schrieb:> Man muss halt wissen was man tut. Ansonsten sollte man ... lieber im> Sandkasten spielen.
Dann gehöre ich wohl (leider) dazu... Bei mir compiliert das nämlich nur
bedingt. Ein konstrukt wie:
> while(*s) {> ...> s++;> }
Compiliert bei mir nur:
- wenn sich das Konstrukt in einer Funktion (also nicht main()) befindet
oder
- Wenn sich das Kontrukt in der main() befindet, und ich einen Pointer
nehme der auf s zeigt und ich den Pointer anstelle von s verwende.
sonst gibts: (s++) error: lvalue required as increment operand
Erklärung? :-/
Grüße
Kaj schrieb:> Compiliert bei mir nur:> - wenn sich das Konstrukt in einer Funktion (also nicht main()) befindet
Ähm. Ist das jetzt ein Scherz?
Es ist eine der Grundregeln von C, dass sich ausführbarer Code immer in
Funktionen befinden muss.
Karl Heinz schrieb:> Ähm. Ist das jetzt ein Scherz?>> Es ist eine der Grundregeln von C, dass sich ausführbarer Code immer in> Funktionen befinden muss.
Ich meinte in einer anderen Funktion als der main()-Funktion.
Karl Heinz schrieb:> Man muss halt wissen was man tut. Ansonsten sollte man das Programmieren> bleiben lassen und lieber im Sandkasten spielen.
Ein Array ist kein Pointer.
Kaj schrieb:> int main(void)> {> char s[20];> char x[20];> strcpy( s, "HALLO" );> strcpy( x, "HALLO" );> foo(s);>> while(*x)> {> x++; // <-- geht nicht: lvalue required as increment operand> }> }
dann muss man es halt anders schreiben.
Rufus Τ. Firefly schrieb:> x ist hier kein Pointer. x ist ein Array.
x ist "nur" eine Adresse, die Startadresse des Arrays! Und genau
deswegen leuchtet mir das auch nicht ein! Nach deiner aussage dürfte
dann
Dirk B. schrieb:> Ein Array ist kein Pointer.Rufus Τ. Firefly schrieb:> Und? Was ist daran unklar? x ist hier kein Pointer. x ist ein Array.
Sagt doch einfach, das es nicht geht, weil ich die Startadresse des
Arrays nicht verändern darf?! (vermute ich jetzt einfach mal)
Kaj schrieb:> void foo(char *s)> {> while(*s)> {> s++; // <-- geht> }> }
Innerhalb der Funktion foo gilt das lokale s. Und das ist als char *s -
also pointer - deklariert. Nenn das einfach um in t und du erkennst den
Unterschied:
>(vermute ich jetzt einfach mal)
@Kaj: Da liegt Dein grundsätzlicher Fehler. Vermuten hat in der
Programmierung nichts zu suchen. Da gibt es klare Regeln. Die gilt es zu
lernen, zu verstehen und anzuwenden.
Macht es doch nicht so kompliziert. Er nicht gemerkt, dass er über den
Funktionsparameter einen cast ausgeführt hat.
(char *) s // wobei s als char s[123] deklariert wurde
That 's all!
muss nochmal fragen ...
warum geht das:
char s[20];
s[0]="h";
s[1]="a";
s[2]="l";
s[3]="l";
s[4]="o";
s[5]=0x00;
lcd_display_string(s);
und das nicht:
char s[20];
strcpy( s, "hallo\0");
lcd_display_string(s);
beim zweiten kommt Müll raus, auch wenn ich das ganze array mit 0x00
voll schreibe
Danke schon mal
Ralph Feuchter schrieb:> und das nicht:>> char s[20];> strcpy( s, "hallo\0");> lcd_display_string(s);>> beim zweiten kommt Müll raus, auch wenn ich das ganze array mit 0x00> voll schreibe
ich sehen keine Fehler, sicher das es nicht funktioniert? die \0 ist
Hallo ist nicht notwendig, stört aber auch nicht.
Peter II schrieb:> ich sehen keine Fehler
Das ist auch nicht der originale Code. Er hat bestimmt wieder das *
benutzt.
Den Wald vor lauter Bäumen nicht sehen passiert jedem einmal. ;-)
Ralph Feuchter schrieb:> char s[20];>> s[0]="h";
Schon der Code muss Fehler, aber zumindest Warnungen liefern.
Du willst einer char-Variablen eine Adresse zuweisen.
"h" ist etwas anderes als 'h'
Daher kann das nicht funktionieren.
Ralph Feuchter schrieb:> muss nochmal fragen ...> warum geht das:
Hm... arbeitest du mit einem PC oder Mikrocontrollern? Evtl. liegen
Strings
in einem besonderen Speicher (z.B. früherer avr-gcc).
Harvard-Architektur?
das ist er schon mittlerweile, der code, meine ich
ich sehs wirklich nicht
char s[20]="";
/*
s[0]="h";
s[1]="a";
s[2]="l";
s[3]="l";
s[4]="o";
s[5]=0x00;
int i;
*/
strcpy( s,"hallo\0");
lcd_display_string(s);
-----------------------------------------
void lcd_display_string(char *s)
{
while(*s)
{
lcd_send_data( *s);
s++;
}
}
wenn ich es direkt zuweise gehts, wenn ich den string kopiere gehts
nicht, aber trotzdem müsste doch in dem Array das Gleiche drin stehen
klausr schrieb:> Hm... arbeitest du mit einem PC oder Mikrocontrollern? Evtl. liegen> Strings
nein, neines soll auf einem Atmega16 laufen. Programmiert wir auf einem
linux PC mit AVR-gcc-Toolchain
s[] geht
u[] ist ganz genau der selbe Misst wie t[] , jedoch die Zeichenzahl
stimmt
char s[20]="";
char t[20]="";
char u[10]="";
s[0]="h";
s[1]="a";
s[2]="l";
s[3]="l";
s[4]="o";
s[5]=0x00;
u[0]='h';
u[1]='a';
u[2]='l';
u[3]='l';
u[4]='o';
u[5]=0x00;
strcpy( t,"hallo");
lcd_display_string(s);
//lcd_display_string(t);
//lcd_display_string(u);
Dirk B. schrieb:> Der bei dir auskommentierte Teil kann so nicht funktionieren.>> "h" ist ein Stringliteral. Du willst aber das Zeichen 'h'.
Das ist mir auch ein Rätsel wie der Teil überhaupt funktionieren soll
wenn du "h" statt 'h' schreibst.
Bist du sicher dass nicht der untere Teil derjenige ist der eigentlich
funktioniert?
maik schrieb:> strcpy kopiert bis zur 0 aber nicht die 0.
klar macht es das. bzw. es fügt an das ziel hinten eine 0 an. Sonst
würde ja im Ziel keine 0 am ende stehen und damit währe es keine
sinnvolle Stringfunktion.
Ralph Feuchter schrieb:> wenn ich es direkt zuweise gehts, wenn ich den string kopiere gehts> nicht, aber trotzdem müsste doch in dem Array das Gleiche drin stehen
Du hast vermutlich ein grundlegendes Problem in deinem Build-Prozess.
Ich tippe darauf, dass du die .data-Section nicht in das HEX-File
exportierst.
Habs raus gefunden woran es lag, an mir natürlich
nicht original schrieb:> Das ist auch nicht der originale Code. Er hat bestimmt wieder das *> benutzt.
das wars zwar nicht ganz, aber so ähnlich
im Unterprogramm wo das Byte in seine nibble zerlegt wird sollte die
adresse übergeben werden und ich hatte das & vergessen.
Vielen Dank an alle, .. habe prima dazugelernt
sorry nochmal
Ralph