Forum: Mikrocontroller und Digitale Elektronik Verständnisprobleme bezüglich Pointer


von Johannes H. (Gast)


Lesenswert?

Hallo Leute,

ich hätte eine Frage bzw. ein Verständnis-Problem und zwar bekomme ich 
immer diese Warnung: "assignment makes pointer from integer without a 
cast".

Ich vermute, dass es ein sehr banaler Fehler ist aber irgendwie stehe 
ich hier komplett auf der Leitung und hoffe, dass Ihr mir da weiter 
helfen könnt.

Der Quellcode diesbezüglich ist hier angeführt (bitte nicht böse sein, 
ist ein Probierbeispiel damit ich die Pointer sowie strtok Funktion 
verstehe):
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main()
5
{
6
    char   delimiter[] = ",";
7
    char  *ptr = NULL;
8
    char        *p_array = NULL;
9
10
    char msg[] = "hallo,wer,bist,du";
11
    p_array = &msg[0];
12
13
   ptr = strtok((char *)p_array, delimiter);         //Warnung
14
  while(ptr != NULL){
15
        printf("%s\n", ptr);
16
  ptr = strtok(NULL, delimiter);      //Warnung
17
  }
18
}

von Sebastian V. (sebi_s)


Lesenswert?

Welcher Compiler? VS, GCC und Clang schlucken das hier ohne Warnung. 
Sehe jetzt auch kein grobes Problem. Der Cast bei "(char *)p_array" ist 
natürlich unnötig, denn p_array ist ja schon ein char*.

von Stefan E. (sternst)


Lesenswert?

string.h nicht inkludiert. Compiler kennt Prototyp der Funktion strtok 
daher nicht und geht per default von Return-Typ int aus. Du weist diesen 
int einem Pointer zu, daher die Warnung.

von Sebastian V. (sebi_s)


Lesenswert?

Das hat man davon wenn man den string.h Header einfach ergänzt...

Ansonsten nächste mal auch alle Warnungen durchlesen. Vor den genannten 
Warnungen gibt GCC noch das hier aus:
strtok.c:14:9: warning: implicit declaration of function 'strtok' 
[-Wimplicit-function-declaration]

Wie ich finde eins der schlimmsten Verbrechen von C sowas als gültigen 
Code durchgehen zu lassen. Wenn ich mit C arbeite dann schalte ich 
sofort die -Werror-implicit-function-declaration GCC Option ein um 
solche Fehler wie oben gar nicht erst compilieren zu lassen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In keiner der von Dir eingebundenen Headerdateien ist strtok 
deklariert.

Damit geht der Compiler von einer Funktion mit dem Rückgabetyp "int" aus 
- und die Zuweisung eines "int" an "char *" führt zur Warnung.

Du müsstet auch eine Warnung erhalten, daß strtok unbekannt ist.

Wenn Du <string.h> einbindest, wird sich das Verhalten ändern.

von Johannes H. (Gast)


Lesenswert?

Ja funktioniert wirklich, wie konnte ich das nur vergessen. Vielen Dank 
:) Hätte es eigentlich funktioniert, wenn ich einen integer-Pointer 
genommen hätte bzw. auf so den Typecast vollzogen hätte:
1
ptr = (int *) ptr;

Ich will nicht nervig sein, nur damit ich es verstehe.

Lg

von Alexander S. (alesi)


Lesenswert?

Johannes H. schrieb:
> Hätte es eigentlich funktioniert, wenn ich einen integer-Pointer
> genommen hätte

Hallo,

hast Du die Antworten von Stefan Ernst und Rufus Τ. Firefly
gelesen (und verstanden)?
Da Du
1
#include <string.h>
vergessen hast, geht der Compiler davon aus, dass
1
strtok
 einen
1
int
zurück gibt. Nur bei
1
int i = strtok(...)
würde fälschlicherweise keine Compilermeldung kommen, aber der code
wäre falsch.

von Ralph S. (jjflash)


Lesenswert?

Johannes H. schrieb:
> ptr = (int *) ptr;

Hä ???

Du hattest schlichtweg nirgendwo eine Definition von

strtok

Mit dem Einbinden von <string.h> wird auch "irgendwo" der entsprechende 
Code hinzugelinkt (niemand kennt deine IDE oder dein Makefile).

von Sebastian V. (sebi_s)


Lesenswert?

Johannes H. schrieb:
> Hätte es eigentlich funktioniert, wenn ich einen integer-Pointer
> genommen hätte bzw. auf so den Typecast vollzogen hätte:

Nein die Warnung sagt etwas anderes. Die Warnung spricht davon das ein 
Integer zu einem Pointer wird ohne Cast. Also etwa sowas:
1
int x;
2
char* c = x;
Dort würde die zweite Zeile die gleiche Warnung produzieren. Wenn man 
die Warnung loswerden will muss man explizit zu einem Pointer casten 
also hier jetzt:
1
char* c = (char*)x;
Integer zu missbrauchen um darin Pointer zu speichern ist aber 
schlechter Stil und fehleranfällig, da die Größe von einem int nicht der 
Größe eines Pointers entsprechen muss.

von Johannes H. (Gast)


Lesenswert?

Ahhh vielen, vielen Dank. Jetzt ist es mir um einiges verständlicher.

von Johannes H. (Gast)


Lesenswert?

Hallo liebe Forenbesucher,

wie schon im Betreff angegeben, habe ich immense Schwierigkeiten mit der 
strtoke Funktion und inzwischen so verzweifelt, dass ich ich euch um Rat 
bitten muss.

Also meine Idee ist es, ein empfangenes Frame (z.B: 1,50000) auf seinen 
Inhalt zu prüfen und aus dem Grund verwende ich strtok, um das Frame zu 
zertrennen. Nur habe ich das Problem, dass ich beim zweiten Charakter 
(in dem Fall "50000") irgendwas anderes erhalte. Beim ersten Charakter 
läuft es solange gut, solange es nur ein Zeichen ist aber sobald ich 
z.B: '10' empfange, kontrolliert er mir nur die '1' und nicht '10' als 
ganzes.


Der Quellcode diesbezüglich ist unten angegeben:
1
int   msg_receive;
2
  int  i = 0;
3
  int  var = 0;
4
  int   delimiter[] = ",";
5
  char  *ptr = NULL;
6
  char  msg[] = "1,10000";
7
8
  ptr = strtok(msg, delimiter);
9
  while(ptr != NULL){
10
    switch (i){
11
      case 0: if (((*ptr >= '1') &&  (*ptr <= '3')) || ((*ptr >= 'S') && (*ptr <= 'R'))){
12
            msg_receive = 1; break;
13
          }
14
          else{
15
            msg_receive = 0; break;
16
          }
17
      case 1: var = atoi(ptr);
18
          if (var > 0 && var <= 999){
19
            msg_receive = 1; break;
20
          }
21
          else{
22
            msg_receive = 0; break;
23
          }
24
      default: msg_receive = 0; break;
25
      }
26
    ptr = strtok(NULL, delimiter);
27
    i++;
28
    if (msg_receive != 1)
29
          break;
30
  }

Ich hoffe, der angeführte Quellcode ist verständlich. Also parallel zu 
Framezerlegung, lasse ich innerhalb einer Switch case Anweisung die 
Richtigkeit des Frames überprüfen. Im ersten Durchgang wird der erste 
Charakter überprüft und im zweiten wird geschaut, ob das enthaltene 
Charakter innerhalb des festgelegten Rahmens ist (hier zwischen 0-999). 
Dazu verwende ich die Funktion atoi, um daraus eben einen Integer zu 
machen.

Ich hoffe Ihr könnt mir hier weiterhelfen.
Lg

von Schorsch X. (bastelschorsch)


Lesenswert?

>'S' && <'R' passt irgendwie nicht.
Ansonsten in unklaren Worten Du sprichst...

von Peter II (Gast)


Lesenswert?

int   delimiter[] = ",";


und
strtok ( char * str, const char * delimiters );

passt irgendwie nicht zusammen.

von Johannes H. (Gast)


Lesenswert?

Klar, da gehört char delimiter, da ist mir anscheinend beim kopieren ein 
fehler passiert. Aber leider löst das mein Problem noch immer nicht ;(

von Peter II (Gast)


Lesenswert?

Johannes H. schrieb:
> Klar, da gehört char delimiter, da ist mir anscheinend beim kopieren ein
> fehler passiert. Aber leider löst das mein Problem noch immer nicht ;(

dann debugge doch einfach, dann sieht man doch wo er etwas anderes macht 
als man erwartet.

von Johannes H. (Gast)


Lesenswert?

Gedebuggt habe ich eh auch schon...beim zweiten teil also bei 500000 
nimmt er mir nur die 5 statt die 500000

von Peter II (Gast)


Lesenswert?

Johannes H. schrieb:
> Gedebuggt habe ich eh auch schon...beim zweiten teil also bei 500000
> nimmt er mir nur die 5 statt die 500000

strtok nimmt überhaupt nichts, er liefert nur einen Pointer. Der hat 
keine länge. Die frage ist wo strtok as 0 Byte einfügt. (ja strtok 
ändert das Orginal)

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.