Forum: PC-Programmierung Kurze C Frage


von bluna (Gast)


Lesenswert?

Hallo,

wahrscheinlich nur eine Verständnisfrage, aaaber:

Mein Eclipse Cdt (gcc unter Kubuntu) frisst mir folgende Zeile nicht:
1
token = strtok(buffer, "#");

Definiert sind token und buffer wie folgt:
1
char buffer[100];
2
char token[10];

Meldung des Compilers:

error: incompatible types when assigning to type ‘char[10]’ from type 
‘char *’

Der Prototyp von strtok ist:
1
char * strtok(char *string, char *delimiters);

token ist bei mir doch ein Zeiger aufs erste Element eines Arrays von 
chars, also ein char *?!

Grüße,
bluna

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

mit char *token sollte das gehen.

token = strtok(buffer, "#");

strtok gibt einen Zeiger zurück und kein Array.

von Marius W. (mw1987)


Lesenswert?

strtok liefert einen Pointer auf den Anfang des Tokens zurück. Aber du 
scheinst das Token aus dem Originalstring herauskopieren zu wollen. Das 
tut strtok nicht. Deshalb auch die Warnung.

Gruß
Marius

von Εrnst B. (ernst)


Lesenswert?

bluna schrieb:
> token ist bei mir doch ein Zeiger aufs erste Element eines Arrays von
> chars, also ein char *?!

Ja, aber:

strtok gibt einen Zeiger zurück, der in "buffer" hineinzeigt.

Wenn du den durch diesen Zeiger bezeichtenen Substring in "token" haben 
willst, brauchst du zusätzlich noch strncpy

von Fabian H. (hdr)


Lesenswert?

strtok gibt Dir die Adresse des Tokens im RAM wieder. Du definierst ein 
Array , welches dann aber gar nicht verwendet wird.

Nimm folgendes:

char *token;

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Haben wir alle gleichzeitig geantwortet ? :-)

strtok() ist nicht ganz mein Favorit um Strings zu zerlegen,
es verändert, in diesem Fall buffer, den zu zerlegenden String.

von bluna (Gast)


Lesenswert?

Danke euch, macht Sinn.

Werd mir wohl am Besten eine eigene Funktion schreiben.

Aber trotzdem, rein vom logischen:
1
char token[10];

Damit reservier ich mir irgendwo im RAM 10 Bytes.

token zeigt mir auf das erste dieser 10 Bytes, ist also ein Zeiger auf 
char (char *).

Kann ich einen Zeiger nornal nicht anweißen, woanders hinzuzeigen?
In diesem Fall eben auf den Rückgabewert von strtok und nicht mehr auf 
meine reservierten 10 Bytes?

Ok, macht natürlich keinen Sinn das ganze, aber vom logischen her, wieso 
funkt das nicht?

Ist ein char[] in Wirklichkeit kein char  sondern ein const char ?

Grüße und Danke,
bluna

von Vlad T. (vlad_tepesch)


Lesenswert?

bluna schrieb:
> token zeigt mir auf das erste dieser 10 Bytes, ist also ein Zeiger auf
> char (char *).

nein, ein Array und ein Zeiger sind nicht das gleiche.
Syntaktisch sind sie in vielen Fällen äquivalent, aber nicht immer.
Der Code den der Compiler erzeugen muss ist signifikant anders.

www.comp.nus.edu.sg/~xujia/Expert.C.Programming.pdf
da gibts ein eigenes Kapitel zu dem Thema:
Seite 86ff:
Chapter 4. The Shocking Truth: C Arrays and Pointers Are NOT the Same!

von bluna (Gast)


Lesenswert?

Danke, werd ich mir gleich mal zu Gemüte führen :)

von Karl H. (kbuchegg)


Lesenswert?

bluna schrieb:

> Aber trotzdem, rein vom logischen:
>
>
1
char token[10];
>
> Damit reservier ich mir irgendwo im RAM 10 Bytes.

richtig.

Du hast das im Speicher erzeugt


   token
   +---+---+---+---+---+---+---+---+---+---+
   |   |   |   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+

10 Speicherzellen, denen du den Namen 'token' gegeben hast.

> token zeigt mir auf das erste dieser 10 Bytes,

nein.

> ist also ein Zeiger auf
> char (char *).

Auch nicht.
Was du hier beschreibst, würde so aussehen

   token
   +-----+
   |  o------+
   +-----+   |
             v
             +---+---+---+---+---+---+---+---+---+---+
             |   |   |   |   |   |   |   |   |   |   |
             +---+---+---+---+---+---+---+---+---+---+


und wie man sieht, ist das etwas völlig anderes.

> Kann ich einen Zeiger nornal nicht anweißen, woanders hinzuzeigen?

Du hast keinen Zeiger.
token ist der Name eines Arrays.

> Ok, macht natürlich keinen Sinn das ganze, aber vom logischen her, wieso
> funkt das nicht?

Weil du etwas missverstanden hast.
In manchen Fällen fungiert der Name eines Arrays als Zeiger auf das 
erste Element. Das bedeutet aber nicht, dass er ein Zeiger IST!
Wenn du eine Variable i hast

   int i = 5;

dann ist bei der Verwendung von i

   j = i;

immer der Inhalt (also die 5) gemeint.

Nur bei Arrays ist das anders. Hast du ein Array

  char a[10];

und verwendest du das Array 'als Ganzes'


   k = a;

dann steht dieses a hier NICHT für die Inhalte des Arrays (so wie beim 
i), sondern für die Startadresse das Arrays im Speicher. Deshalb ist a 
aber kein Pointer. a ist immer noch ein Array mit einer im Speicher 
festen Speicheradresse.

von Michl (Gast)


Lesenswert?

ich bin gerade über diesen Thread gestolpert, nachdem ich ein ähnliches 
Problem habe.

Viele Funktionen (zB Stringausgaben auf LCD oder USART) zählen ja den 
stringpointer hoch fürs zeichenweise ausgeben des strings.
1
while(string++)

Wenn ich in einer Funktion einen lokalen String habe und diesen 
inkrementieren will bekomme ich auch einen Compilerfehler.
1
char string[10];
2
...
3
...
4
string++;
Das geht nicht.

Ist dafür auch das von Karl Heinz Buchegger geschilderte Prinzip 
verantwortlich?

Beste Grüße, der Michl

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Michl schrieb:
> Wenn ich in einer Funktion einen lokalen String habe und diesen
> inkrementieren will bekomme ich auch einen Compilerfehler.

Es ist halt doch ein Unterscheid zwischen einem String und einem
Pointer. In Deinem Beispiel gibt man das dann so aus:

[c]
char *p;

for ( p=string; *p; p++)
  putchar( *p);
[c]

von DirkB (Gast)


Lesenswert?

Michl schrieb:
> Ist dafür auch das von Karl Heinz Buchegger geschilderte Prinzip
> verantwortlich?

Ja.

Ein Array ist kein Pointer.

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.