C: dickes String Problem

#2986602
Lesenswert?

Hallo leute, habe ein dickes Problem.
jedes mal wenn ich im Programm eine String funktion benutze, werden mir 
solche fehler vom GCC ausgegeben :

>michael@debian:~/vfd$ gcc string_kopieren1.c
>string_kopieren1.c: In function ‘vfd_printlu’:
>string_kopieren1.c:6: warning: initialization makes integer from pointer >without 
a cast
>string_kopieren1.c:10: warning: passing argument 1 of ‘strlen’ makes >pointer 
from integer without a cast
>/usr/include/string.h:397: note: expected ‘const char *’ but argument is >of type 
‘char’
>string_kopieren1.c:12: error: switch quantity not an integer
>string_kopieren1.c: In function ‘main’:
>string_kopieren1.c:47: warning: passing argument 1 of ‘vfd_printlu’ makes 
>pointer from integer without a cast
>string_kopieren1.c:5: note: expected ‘char *’ but argument is of type >‘char’
>string_kopieren1.c:47: warning: passing argument 2 of ‘vfd_printlu’ makes 
>pointer from integer without a cast
>string_kopieren1.c:5: note: expected ‘int *’ but argument is of type ‘int’


hier mal der code dazu:
1
#include <stdio.h>
2
#include <string.h>
3
FILE *dateimerker;
4

5
int vfd_printlu(char *val, int *fmt)
6
{ char s1= val;
7
  char s2[12];
8
  int lauf, size;
9
  
10
  size = strlen (s1);
11
  
12
  switch(fmt)
13
   {
14
   case 0:fprintf(dateimerker, "\x1B[1;1H");
15
          fprintf(dateimerker,"Der Wert:%s",s1); 
16
          fflush(dateimerker);
17
           break;
18
   case 1: 
19
           break;
20
   case 2:
21
           break;
22
   case 3:
23
           break;
24
   case 4: return 0; break;
25
   }
26

27
   return 0; 
28
}
29

30
int main(void)
31
{ char val;
32
  int fmt;
33
  
34
  printf("\t FMT\n");
35
  printf("Bitte Zahl eingeben:\n");
36
  scanf("%c", &val);
37
  
38
  
39
  printf("Bitte Format auswÀhlen:\n");
40
  printf("0=   xxxxxxxxx\n");
41
  printf("1= xxx xxx xxx\n");
42
  printf("2= xxx.xxx.xxx\n");
43
  printf("3= xxxMxxxKxxx\n");  
44
  printf("4= EXIT\n");
45
  scanf("%u",&fmt);
46

47
  vfd_printlu(val, fmt);
48
  return 0;
49

50
}

währe schön wenn ihr mir ein paar tipps geben könntet. Komme nicht 
weiter -_-

Danke im vorraus,
Michael
#2986611
Lesenswert?

Michael Hakenkötter schrieb:

>  char s1= val;

s1 ist aber kein String.
s1 ist eine Variable, in der 1 Character gespeichert wird. NIcht mehr 
und nicht weniger.
Ein String ist aber was anderes.

Aber wahrscheinlich meintest du hier

   char *s1 = val;

da val ja auch ein char * ist.


> währe schön wenn ihr mir ein paar tipps geben könntet.

Achte mehr auf die Datentypen!
Eine Variable hat neben ihrem Wert eine zweite wichtige Eigenschaft. 
Nämlich: von welchem Typ ist sie!
Du hast noch mehr Fehler in deinem Programm, die darauf zurückzuführen 
sind, dass du dir keine Gedanken um Datentypen gemacht hast. Ein int und 
ein Pointer auf int sind nicht dasselbe.
#2986620
Lesenswert?

Karl Heinz Buchegger schrieb:
> da val ja auch ein char * ist.

Aber auch nur innerhalb von vfd_printlu, in main ist es auch ein char, 
was auch wieder für Warnungen sorgt.

Michael: "char" und "char *" sind unterschiedliche Typen. Guck Dir an 
wie du sie verwendest und wo da was nicht passt.

Genauso ist "int *" etwas anderes als "int". Und darüber beschwert er 
sich bei dem switch.

Viele Grüße,
         Simon
#2986633
Lesenswert?

Simon Budig schrieb:
> Karl Heinz Buchegger schrieb:
>> da val ja auch ein char * ist.
>
> Aber auch nur innerhalb von vfd_printlu, in main ist es auch ein char,
> was auch wieder für Warnungen sorgt.

Yep. Habs zu spät gesehen, dass da ja auch alles schief ist.

Wobei: Wenn ich mal versuche die ganze Aufgabenstellung zu erraten dann 
bezweifle ich, dass das ganze überhaupt etwas mit Strings zu tun hat, 
bzw. dass der
  char val;
in main() richtig ist.
Ich sehe nicht, wie man mit dem Zahlenbereich eines char die 
Formatiervorschläge sinnvoll umsetzen kann.
#2986642
Lesenswert?

Michael Hakenkötter schrieb:
> wenn ich jetzt aber die zeiger wegnehme:
>
>
1
> int vfd_printlu(char val, int fmt)
2
> { char s1[12]= val;
3
>   char s2[12];
4
>   int lauf, size;
5
> 
6
>   size = strlen (s1);
7
>
>
> gibts erstmal sowas:
>
>>michael@debian:~/vfd$ gcc string_kopieren2.c
>>string_kopieren2.c: In function ‘vfd_printlu’:
>>string_kopieren2.c:6: error: invalid initializer

na ja.
Was ist denn ein Initializer?
Das womit etwas initialisiert wird.

Wo wird bei dir etwas initialisiert?
Hier
  char s1[12]= val;

So. Wie lautet die Syntax mit der Arrays initialisiert werden?



Ich denke wir laufen im Moment gerade in die Richtung: Du probierst 
planlos alles mögliche durch, ohne dir irgendwelche Gedanken zu machen 
und Fehlermeldungen postest du einfach hier her in der Hoffnung 
irgendwer wird sich irgendwann erbarmen und dir einfach fertigen, 
korrekten Code vor den Latz knallen.
#2986644
Lesenswert?

Karl Heinz Buchegger schrieb:
> Wobei: Wenn ich mal versuche die ganze Aufgabenstellung zu erraten dann
> bezweifle ich, dass das ganze überhaupt etwas mit Strings zu tun hat,
> bzw. dass der char in main() richtig ist.

Ja, die aufgabenstellung ist die ausgabe der zahl "val" auf ein VFD 
display.
Dies natürlich in verschiedenen formaten, wie in der void main() schon 
beschrieben. also dacht ich mir den String von hinten her stück für 
stück auf s2[] kopieren, und dann als 4. und wenn die zahl länger ist 
auch als 8. zeichen dann die trenner einzufügen.
also strcpy.
oder?
#2986646
Lesenswert?

Michael Hakenkötter schrieb:
> wenn ich jetzt aber die zeiger wegnehme:

Bitte tue uns einen Gefallen und versuche, unsere Hinweise ernst zu 
nehmen und zu verstehen.

Keiner hat Dir empfohlen "die Zeiger wegzunehmen". Du musst ein 
Verständnis dafür entwickeln, was der Unterschied zwischen einem 
Zeigertypen und einem "normalen" Typ ist.

Das können wir Dir hier im Forum nicht klein in klein 
auseinanderklamüsern, das musst Du Dir schon selbst anlesen. Der Link 
von HutHut wäre da z.B. ein Anfang.

Viele Grüße,
        Simon
#2986653
Lesenswert?

Michael Hakenkötter schrieb:
> Karl Heinz Buchegger schrieb:
>> Wobei: Wenn ich mal versuche die ganze Aufgabenstellung zu erraten dann
>> bezweifle ich, dass das ganze überhaupt etwas mit Strings zu tun hat,
>> bzw. dass der char in main() richtig ist.
>
> Ja, die aufgabenstellung ist die ausgabe der zahl

Eben.
Eine Zahl!

Wo kommt da ein char ins Spiel?
Einen char benutzt man, wenn man Buchstaben speichern will (wobei 
natürlich der Begriff 'Buchstabe' nicht wortwörtlich zu nehmen ist. Auch 
'1' ist ein Buchstabe, weil er ja einen ASCII Code hat und ja eigentlich 
nur dieser ASCII Code in der Variablen gespeichert wird. Im weitesten 
Sinne kann man einen char daher auch so auffassen: Eine Variable mit der 
man einen kleinen INteger speichern kann. Wobei die Betonung auf 'klein' 
liegt! Denn ja nachdem ob ein char signed oder unsigned ist, ist der 
zulässige Wertebereich 0 bis 255 bzw. -128 bis +127. In dem Moment, in 
dem du allerdings einen scanf mit %c machst, ist es mit dieser 
Verwendung vorbei. Du kannst dann auf deiner Tastatur gerade mal 1 Taste 
drücken und das wars dann für den scanf. Und ich kann mir nicht 
vorstellen, dass es das ist, was du möchtest. Denn die Hauptverwendung 
von char auf einem PC besteht nun mal darin, einen einzelnen Buchstaben 
('A', '+', '&', '3', etc. etc.) zu speichern. Und in diesem Zusammenhang 
machen deine angedeuteten Formatiervorschläge überhaupt keinen Sinn.

WEas aber auf keinen Fall geht: einen kompletten String in einem 
einzelnen char abspeichern (ausser einem leeren String. Aber das ist 
selten sinnvoll)
#2986666
Lesenswert?

Karl Heinz Buchegger schrieb:
>> Ja, die aufgabenstellung ist die ausgabe der zahl
>
> Eben.
> Eine Zahl!

Man kann die Formatierung einer Zahl auch als String-Manipulation 
auffassen. Wenn man statt dem scanf ("%c"...) einen String einlesen 
würde (und annimmt, dass der Benutzer nur Ziffern eingibt - etwas 
gewagt...) dann kann man da sehr schematisch die Punkte/M/K's aus den 
vorgegebenen Formaten einsetzen, ohne dass man das als echte Zahl 
auffassen muss.

Ob das der Aufgabenstellung entspricht können wir hier erstmal nicht 
richtig beurteilen...

Viele Grüße,
         Simon
#2986676
Lesenswert?

Michael Hakenkötter schrieb:
> ein C-Buch zu verwenden wurde uns vom lehrer untersagt, da sein
> unterricht so allumfassend ist -.- (wie man sieht)...

Die Ausrede hab ich noch nie gehört.

(Ignorier deinen Lehrer. Ohne C-Buch kommst du nicht weit. Und nein. Ich 
kenne keinen Lehrer, der auch was drauf hat, der einem Literatur 
untersagen würde. Eher das Gegenteil. Denn die, die tatsächlich gut sind 
wissen, dass sie in einem Vortrag viele Details vergessen zu erwähnen, 
bzw. nicht die notwendige konsquente Linie durch den Lehrstoff 
durchziehen. Etwas was ein Buch, das von vielen Leuten Korrektur gelesen 
wurde, problemlos kann.)
#2986892
Lesenswert?

soooooo,
habe mal was anderes ausprobiert.
habe mit der funktion "snprintf" die daten unsigned long val in einen 
string kopiert.
hier ist schon ein fehler...warum weis ich nicht. habe beispiele 
angeschaut, die aber die gleiche formartierung wählen.
1
#include <stdio.h>
2
#include <string.h>
3
FILE *dateimerker;
4

5
int vfd_printlu(unsigned long val, int fmt)
6
{ int zahl [11];  //modifizierte zeichenkette
7
  int zahl1[10] ;  //max. 9 zeichen
8
  
9
  snprintf( zahl1, 10, "%lu", val); // unsigned long val auf int zahl 1 "kopieren"
10
  
11
  switch(fmt)
12
   {
13
   case 0:printf("%s\n",zahl);
14
           break;
15
           
16
   case 1:       zahl[11]= '\0';
17
                 zahl[10]= zahl1[8];
18
                 zahl[9] = zahl1[7];
19
                 zahl[8] = zahl1[6];
20
                 zahl[7] = ' '; 
21
                 zahl[6] = zahl1[5];
22
                 zahl[5] = zahl1[4];
23
                 zahl[4] = zahl1[3];
24
                 zahl[3] = ' ';
25
                 zahl[2] = zahl1[2];
26
                 zahl[1] = zahl1[1];
27
                 zahl[0] = zahl1[0];
28
          printf("eingabe: %s\n", zahl1);        
29
          printf("ausgabe: %s\n", zahl);    
30

31
           break;
32
           
33
   case 2:       zahl[11]= '\0';
34
                 zahl[10]= zahl1[8];
35
                 zahl[9] = zahl1[7];
36
                 zahl[8] = zahl1[6];
37
                 zahl[7] = '.'; 
38
                 zahl[6] = zahl1[5];
39
                 zahl[5] = zahl1[4];
40
                 zahl[4] = zahl1[3];
41
                 zahl[3] = '.';
42
                 zahl[2] = zahl1[2];
43
                 zahl[1] = zahl1[1];
44
                 zahl[0] = zahl1[0];
45
          printf("eingabe: %s\n", zahl1);        
46
          printf("ausgabe: %s\n", zahl);
47
           break;
48
           
49
   case 3:       zahl[11]= '\0';
50
                 zahl[10]= zahl1[8];
51
                 zahl[9] = zahl1[7];
52
                 zahl[8] = zahl1[6];
53
                 zahl[7] = 'K'; 
54
                 zahl[6] = zahl1[5];
55
                 zahl[5] = zahl1[4];
56
                 zahl[4] = zahl1[3];
57
                 zahl[3] = 'M';
58
                 zahl[2] = zahl1[2];
59
                 zahl[1] = zahl1[1];
60
                 zahl[0] = zahl1[0];
61
          printf("eingabe: %s\n", zahl1);        
62
          printf("ausgabe: %s\n", zahl);
63
           break;
64
           
65
   case 4: return 0; break;
66
   }
67

68
   return 0; 
69
}
70

71
int main(void)
72
{ unsigned long val;
73
  int fmt;
74
  
75
  printf("\t FMT\n");
76
  printf("Bitte Zahl eingeben:\n");
77
  scanf("%lu", &val);
78
  
79
  
80
  printf("Bitte Format auswÀhlen:\n");
81
  printf("0=   xxxxxxxxx\n");
82
  printf("1= xxx xxx xxx\n");
83
  printf("2= xxx.xxx.xxx\n");
84
  printf("3= xxxMxxxKxxx\n");  
85
  printf("4= EXIT\n");
86
  scanf("%u",&fmt);
87

88
  vfd_printlu(val, fmt);
89
  return 0;
90

91
}

und der string "zahl[12]" wird nicht bearbeitet.. warum?

>michael@debian:~/vfd$ gcc noch_eins_3.c
>noch_eins_3.c: In function ‘vfd_printlu’:
>noch_eins_3.c:9: warning: passing argument 1 of ‘snprintf’ from >incompatible 
pointer type
>/usr/include/stdio.h:363: note: expected ‘char * __restrict__’ but >argument is 
of type ‘int *’
>michael@debian:~/vfd$ a.out
>   FMT
>Bitte Zahl eingeben:
>123456789
>Bitte Format auswÀhlen:
>0=   xxxxxxxxx
>1= xxx xxx xxx
>2= xxx.xxx.xxx
>3= xxxMxxxKxxx
>4= EXIT
>2
>eingabe: 123456789
>ausgabe: 123456789
#2986907
Lesenswert?

Michael Hakenkötter schrieb:
>>michael@debian:~/vfd$ gcc noch_eins_3.c

Verwende - gerade als Anfänger - gcc -Wall

Du willst soviele Warnungen wie möglich. Und dann...

>>noch_eins_3.c: In function ‘vfd_printlu’:
>>noch_eins_3.c:9: warning: passing argument 1 of ‘snprintf’ from >incompatible 
pointer type
>>/usr/include/stdio.h:363: note: expected ‘char * __restrict__’ but >argument is 
of type ‘int *’

...willst Du die nicht ignorieren  :-)

Viele Grüße,
         Simon
#2986948
Lesenswert?

Michael Hakenkötter schrieb:
> Nuja aber als anfänger hat man angst vor -wall

Warum sollte das so sein.
Wenn der Compiler eine Warnung gibt, dann hat das einen Grund.
Und in deinem Stadium ist es so, dass dieser Grund in 99% aller Fälle 
gerechtfertigt ist. Du wirst momentan nur auf sehr wenige Warnungen 
stossen, die tatsächlich harmlos sind.

>
> aber ich weis jetzt das ich mich string und pointermäßig noch mal aufn
> popo setzen muss und mir ein buch zulegen sollte. irgendwelche
> empfehlungen?

Wie immer. Die klassische Bibel "Kernighan&Ritchie Programming in C" in 
der englischen Originalausgabe (die deutsche Übersetzung soll furchtbar 
sein, aber das Original ist ok)
#2986960
Lesenswert?

> ja mit ignorieren ist so eine sache, kopieren tut er den string ja...

Mir gefällt nicht, dass du hier den Terminus 'kopieren' benutzt. Da wird 
nichts kopiert.
snprintf ERZEUGT eine Textrepräsentierung (vulgo 'String') einer Zahl.

Die Zahl 654 ist etwas völlig anderes als der String "654". Das eine ist 
ein 'Ding' mit dem man rechnen kann, etwas mit dem ein Mengenbegriff (im 
Sinne von Stricherln an der Wand, im Sinne einer Anzahl von Streihhölzer 
die vor dir liegen) verbunden ist. Das andere ist nur ein Text, der aus 
den Buchstaben '6', '5', '4' und '\0' besteht. Dieser Text könnte 
genausogut "Helmut" lauten, oder "$%&"§#*". In diesem Fall ist der Text 
aber so aufgebaut, dass er eine Textrepräsentierung der Zahl 654 
darstellt, so dass wenn man den Text irgendwo ausgibt, dann an dieser 
Ausgabe eben nicht "Helmut" steht, sondern "654", was ein Mensch 
wiederrum durch seine Vorbelastung als 'Zahl' 654 liest. Aber im Grunde 
steht da keine Zahl an der Ausgabe, sondern einfach nur ein Text.

In diesem Sinne kopiert snprintf nichts. snprintf erzeugt einen Text. 
Nämlich den Text, den wir Menschen sehen wollen, wenn die als Argument 
angegebene Zahl den Wert 654 hat.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren