Forum: Compiler & IDEs GCC und Raspberry Pi


von Sven B. (mainframeosx)


Lesenswert?

Ich habe hier ein Problem mit dem gcc unter Raspberry Pi
Die Version ich nutze ist:
gcc (Debian 4.6.3-14+rpi1) 4.6.3

ich jetzt folgendes:

part[0]="start";
result=strcmp(&parts[0],"start");

erhalte ich 10 als Rückgabewert.Ist das richtig.

Wenn ich jetzt eine Überprüfung mit der Anweisung unten durchführe:

if (strcmp(&parts[0],"start")==10){
  printf("start found");
      }

was aber nicht geht.Warum auch immer.

Jemand eine Idee. Den Programmcode habe ich von einem
AVR Projekt übernommen, und da funktioniert alles.

Danke im voraus?

von (prx) A. K. (prx)


Lesenswert?

&parts[0] ist die Adresse des Pointer auf den String. Nicht die Adresse 
des Strings. Compilerwarnung igmoriert?

von foo (Gast)


Lesenswert?

Die Funktion strcmp gibt dir 0 zurück wenn die Strings gleich sind, oder 
eine beliebige(!) Zahl kleiner oder größer 0 wenn nicht.

Der Zahlenwert 10 hat keinerlei Bedeutung.

Im Übrigen würde das Ergebnis 10, da es ungleich null ist, bedeuten, 
dass "start" eben nicht gefunden wurde.

von Frank (Gast)


Lesenswert?

1
Returns an integral value indicating the relationship between the strings:
2
return value  indicates
3
<0  the first character that does not match has a lower value in ptr1 than in ptr2
4
0  the contents of both strings are equal
5
>0  the first character that does not match has a greater value in ptr1 than in ptr2


Sie sind also nicht gleich!
Warum wohl?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Man müsste jetzt noch wissen, von welchem Datentyp part und parts
sind und ob diese beiden Variablen in irgendeiner Form gemeinsamen
Speicher nutzen.

von Rolf M. (rmagnus)


Lesenswert?

Sven Schwiecker schrieb:
> if (strcmp(&parts[0],"start")==10){
>   printf("start found");
>       }
>
> was aber nicht geht.Warum auch immer.

Die Ausgabe ist zeilengepuffert. Da deinem printf() das \n fehlt, 
verbleibt der Text erstmal im Puffer.

von Yalu X. (yalu) (Moderator)


Lesenswert?

In folgendem Kontext (C++) würde die strcmp-Funktion tatsächlich 0
liefern und somit in der Ausgabe
1
start found

erscheinen:

1
#include <cstdio>
2
#include <cstring>
3
4
using namespace std;
5
6
const char *part[1];
7
const char *&parts = part[0];
8
9
int main(void) {
10
  part[0] = "start";
11
  if (strcmp(&parts[0], "start") == 0) {
12
    printf("start found\n");
13
  }
14
  return 0;
15
}

von Sven B. (mainframeosx)


Lesenswert?

Ich habe es mal so abgeändert:
Beim Ergebnis für start passt das jetzt , aber beim cmd passt das nicht.
und wieso geht das bei meinem AVR Project?

  char *t;
  int i;
  int result;
        char *parts[200];
        char *last=0;
  char *token=0;
  char **item = parts;

  token = strtok_r(command, " ", &last);
        while (token) {
            *(item++) = token;
            token = strtok_r(NULL, " ", &last);
          }
      printf("1 %s\n",parts[0]);
      printf("2 %s\n",parts[1]);
      result=strcmp(parts[0],"start");
      printf("Test %d\n",strcmp(parts[0],"start"));
      result=strcmp(parts[1],"cmd");
      printf("Test %d\n",strcmp(parts[1],"cmd"));

Kleine Änderung:

wenn ich beim cmd string noch ein \n setze sind beide Ergebnisse wie
sie sein sollten, wie kann ich beim String den ESC Charakter entfernen.

von Hans (Gast)


Lesenswert?

Kann es sein, dass Du gar keinen Speicher für die Zeichen allokiert hast 
und nur Zeiger auf Stringliterale speicherst? Wenn Du dann versuchst, 
die zu verändern, kann alles mögliche passieren ...

von Sven B. (mainframeosx)


Lesenswert?

Am Anfang vom Programm erstelle ich:

char command[8192];

das sollte doch reichen oder?

von Hans (Gast)


Lesenswert?

In dem Code-Ausschnitt sehe ich keinen Zusammenhang zwischen "command" 
und "parts".

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sven Schwiecker schrieb:
> Am Anfang vom Programm erstelle ich:
>
> char command[8192];
>
> das sollte doch reichen oder?

Und woher sollen wir das wissen? Wo initialisierst Du Dein Pointer-Array 
parts?

Zeige den gesamten Code. Glaskugelpolieren ermüdet.

von Rolf M. (rmagnus)


Lesenswert?

Sven Schwiecker schrieb:
> wenn ich beim cmd string noch ein \n setze sind beide Ergebnisse wie
> sie sein sollten, wie kann ich beim String den ESC Charakter entfernen.

Dann scheint dein command-String (auf welche gemeime Art er auch immer 
befüllt wird) ein \n am Ende zu haben.

Hans schrieb:
> In dem Code-Ausschnitt sehe ich keinen Zusammenhang zwischen "command"
> und "parts".

Rufus Τ. Firefly schrieb:
> Wo initialisierst Du Dein Pointer-Array parts?

Das sollte doch erkennbar sein:
1
  char *parts[200];
2
  char **item = parts;
3
4
  token = strtok_r(command, " ", &last);
5
  
6
  // und in der Schleife:
7
      *(item++) = token;

von Sven B. (mainframeosx)


Lesenswert?

Genau das ist das Problem:

"\n".....

Aber ich habe folgendes gefunden:

  command[strlen(command)-1]=32;
  command[strlen(command)]=0;

und Tara, jetzt geht es.

von Mitlesender (Gast)


Lesenswert?

Mal so nebenbei:
1
part[0] = "start";
So etwas habe ich noch nie gelesen. Gibt's denn da keine Warnung wie 
'Initialisierer zu lang' oder so?

Oder sind die wichtigen Warnungen Arduino-kasperlemäßig abgeschaltet?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mitlesender schrieb:
> Mal so nebenbei:
>
1
> part[0] = "start";
2
>
> So etwas habe ich noch nie gelesen. Gibt's denn da keine Warnung wie
> 'Initialisierer zu lang' oder so?

Dann solltest Du Dir mal ein C-Buch schnappen. Warum sollte es denn da 
eine Warnung geben?

Hier die Definition von part:

  const char *part[1];

Das ist ein Array von Zeigern. Offenbar hast Du das Sternchen überlesen. 
Im ersten Element wird nun ein Zeiger gespeichert - nämlich dieser, 
welcher auf "start" zeigt.

Man mag sich vielleicht über die Sinnigkeit der Array-Größe von eins 
streiten, aber das passt sonst absolut. Es wird auch keine Warnung 
ausgeben - auch nicht mit -Wall.

$ cat part.c
1
const char *part[1];
2
3
void x ()
4
{
5
    part[0] = "start";
6
}
1
$ cc -c -Wall part.c
2
$

> Oder sind die wichtigen Warnungen Arduino-kasperlemäßig abgeschaltet?

Eher scheint Dein Parser kasperlemäßig abgeschaltet ;-)

von Rolf Magnus (Gast)


Lesenswert?

Sven Schwiecker schrieb:
> Genau das ist das Problem:
>
> "\n".....
>
> Aber ich habe folgendes gefunden:
>
>   command[strlen(command)-1]=32;
>   command[strlen(command)]=0;
>
> und Tara, jetzt geht es.

Spricht was dagegen, beim strtok das \n noch in der Delimeter-Liste 
aufzunehmen?

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:
> Sven Schwiecker schrieb:
>> Genau das ist das Problem:
>>
>> "\n".....
>>
>> Aber ich habe folgendes gefunden:
>>
>>   command[strlen(command)-1]=32;
>>   command[strlen(command)]=0;
>>
>> und Tara, jetzt geht es.
>
> Spricht was dagegen, beim strtok das \n noch in der Delimeter-Liste
> aufzunehmen?


Wäre eine Möglichkeit.

@TO
Aber selbst wenn du den \n nicht bei den Delimitern haben willst:
Wenn du ein Leerzeichen meinst, dann schreib auch 'Leerzeichen'.
1
  command[strlen(command)-1] = ' ';

Was es allerdings für einen Sinn haben soll, die String-Terminierung 
noch mal zu beschreiben, erschliesst sich mir nicht. An der Stelle 
command[strlen(command)] muss bereits ein '\0' Zeichen stehen. Das geht 
gar nicht anders, da strlen genau an der Position dieses Zeichens die 
Stringlänge festmacht. Mit anderen Worten:
Das hier
1
   command[strlen(command)]=0;
ist eine 0-Operation. Sie hat keinen Zweck, ist sinnlos und sofern der 
Compiler sie nicht wegoptimiert, verbraucht sie nur Rechenzeit (für den 
strlen)

von Sven B. (mainframeosx)


Lesenswert?

@Frank M.:

Äh, wieso Arduino? Es geht hier um den Raspberry Pi und GCC!

von Markus F. (mfro)


Lesenswert?

strcmp() gibt keinesfalls "irgendeinen zufälligen" Wert zurück, sondern 
einen Wert < 0 (wenn der erste String lexikalisch kleiner als der zweite 
ist), = 0 (wenn beide Strings gleich sind) oder >0 (wenn der erste 
String lexikalisch größer als der zweite ist).

Tatsächlich ist es so, daß viele Implementierungen die numerische 
Differenz der beiden Zeichen an der Stelle zurückgeben, an der sich die 
Strings unterscheiden.

Und das ist offensichtlich auch hier der Fall: der Rückgabewert von 10 
kommt zustande, weil hier "10 - 0" gerechnet wird. Das Stringende-'\0' 
des zweiten Strings wird vom '\n' (=10) - Byte im ersten abgezogen -> 
strcmp() beschließt, daß die beiden Strings unterschiedlich sind und 
gibt die Differenz der beiden Zeichen zurück.

Die eigentliche Frage ist aber nicht, warum da 10 zurückgegeben wird, 
sondern was das '\n' da am Stringende zu suchen hat.

Das ist wohl schon beim Einlesen des Strings (wo auch immer der 
herkommt) schief gelaufen und das Problem gehört desewegen auch dort 
korrigiert.

von Sven B. (mainframeosx)


Lesenswert?

@ Markus F. ->

http://www.sharpcam.co.uk/RS232-Communications/Getting-Started.aspx

Characters to send at end of line
Typically a carriage return and line feed are required. To specify a 
character(s) first choose the desired character from the ASCII Table 
Enclose the corresponding decimal value for each character in <> 
brackets, without any form of punctuation in between. For example: <13> 
for carriage return and <10> for line feed. This is the default when you 
create a new RS232 Settings for a machine.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.