Forum: PC-Programmierung C: dickes String Problem


von Michael H. (m0ddmylife)


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

von Karl H. (kbuchegg)


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.

von Simon B. (nomis)


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

von HutHut (Gast)


Lesenswert?

Declariert ist:
char val;

angewendet wird:
char val;

erwartet wird:
char* val;

gleiches gilt für:
int fmt

see: http://www.tutorials.at/c/11-zeiger.html

von Karl H. (kbuchegg)


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.

von Michael H. (m0ddmylife)


Lesenswert?

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);

gibts erstmal sowas:

>michael@debian:~/vfd$ gcc string_kopieren2.c
>string_kopieren2.c: In function ‘vfd_printlu’:
>string_kopieren2.c:6: error: invalid initializer

von Karl H. (kbuchegg)


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.

von Michael H. (m0ddmylife)


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?

von Simon B. (nomis)


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

von Michael H. (m0ddmylife)


Lesenswert?

ok danke erstmal. ich werd mir das mal durchlesen und im besten falle 
auch verstehen. sonst meld ich mich wieder ;)

von Karl H. (kbuchegg)


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)

von Karl H. (kbuchegg)


Lesenswert?

Noch ein Link-Tip. Denn ich orte hier ein komplettes Nicht-Verstehen, 
was denn eigentlich Strings in C sind und wie man mit ihnen arbeitet.

String-Verarbeitung in C

Welches C-Buch benutzt du?

von Simon B. (nomis)


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

von Michael H. (m0ddmylife)


Lesenswert?

ein C-Buch zu verwenden wurde uns vom lehrer untersagt, da sein 
unterricht so allumfassend ist -.- (wie man sieht)...

von Karl H. (kbuchegg)


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.)

von Simon B. (nomis)


Lesenswert?

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

Uh, da hat jemand Angst, dass seine Autorität untergraben wird, weil 
jemand etwas besser wissen könnte...

Ignoriere das Verbot.

Viele Grüße,
         Simon

von Michael H. (m0ddmylife)


Lesenswert?

Danke, das werde ich wohl mal tun jetzt ;)

von Michael H. (m0ddmylife)


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

von Simon B. (nomis)


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

von Michael H. (m0ddmylife)


Lesenswert?

ja mit ignorieren ist so eine sache, kopieren tut er den string ja...
aber er bearbeitet ja den string nicht so wie ich das will und fügt die 
trennzeichen nicht ein. siehe ergebnis eingabe und dann die ausgabe

von DirkB (Gast)


Lesenswert?

zahl und zahl1 sollten schon char-Arrays sein.
Und du hast noch zahl[11] bei der Definition stehen.

von Michael H. (m0ddmylife)


Lesenswert?

Leck a****... genial :D

DANKEEEEEEEEE!!!!


:D

von DirkB (Gast)


Lesenswert?

Das hat der Compiler doch gemeldet mit seinen Warnungen.

Warnungen darf man nur ignorieren, wenn man weiß was man tut.
Sonst sollte man sie wie Fehler behandeln.

von Michael H. (m0ddmylife)


Lesenswert?

Nuja aber als anfänger hat man angst vor -wall

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?

von Karl H. (kbuchegg)


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)

von Karl H. (kbuchegg)


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.

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.