Hallo,
ich möchte einen ganz normalen String zuweisen aber irgendwie will der
Compiler nicht... ich hab schon im Tutorial nachgeschaut und auch nach
Anweisung gemacht.
Bitte um Hilfe !
Micha schrieb:> ich hab schon im Tutorial nachgeschaut und auch nach> Anweisung gemacht.
glaube ich nicht, weil sotwas in C nicht geht. Du musst den String
Kopieren
strcpy(mode,"Hallo");
oder noch etwas sichere
strncpy(mode,"Hallo", sizeof(mode) );
elmo schrieb:> strncpy(mode,"Hallo",sizeof(mode));
schön das andere den gleichen fehler machen wie ich, richtig müsste es
so sein:
strncpy(mode,"Hallo",sizeof(mode)-1);
Peter schrieb:> schön das andere den gleichen fehler machen wie ich, richtig müsste es> so sein:>> strncpy(mode,"Hallo",sizeof(mode)-1);
Nein, das war schon korrekt so. Man kann aber (und sollte eigentlich),
um sicher zu stellen, dass der neue String terminiert ist,
dazuschreiben:
Peter schrieb:>> strncpy(mode,"Hallo",sizeof(mode));
Soweit passt es, solange man sich konsequent darüber im Klaren ist, dass
mode[] nicht zwangsläufig eine 0 hinten dran hat.
> strncpy(mode,"Hallo",sizeof(mode)-1);
Aber das das ist nun für sich allein wirklich falsch, weil es sich bei
mode[] um eine nicht initialisierte lokale Variable handelt und im
letzten Byte Müll statt 0 drin steht. Da fehlt noch:
mode[sizeof(mode)-1] = '\0';
Siehe auch strlcpy, als besser konzipierte Version von strncpy.
Peter schrieb:> so jetzt aber sollte es sauber sein.
Nein. Nun steht im ersten Byte 0, aber im letzten steht immer noch Müll.
Formal korrekt in C99, aber Kandidat für den Schwachfugpreis, wäre
char mode[7] = {0,0,0,0,0,0,0};
was aber bei lokalen Variablen und C89/C90 ebensowenig geht wie deine
Version, weil sich solche Arrays nicht initialisieren lassen.
A. K. schrieb:> Nein. Nun steht im ersten Byte 0, aber im letzten steht immer noch Müll.
das glaube ich nun nicht, weil es {0} meines wissen den completten
string mit \0 anlegt.
A. K. schrieb:> Peter schrieb:>>> so jetzt aber sollte es sauber sein.>> Nein. Nun steht im ersten Byte 0, aber im letzten steht immer noch Müll.>> Formal korrekt in C99, aber Kandidat für den Schwachfugpreis, wäre> char mode[7] = {0,0,0,0,0,0,0};> was aber bei lokalen Variablen und C89/C90 ebensowenig geht wie deine> Version, weil sich solche Arrays nicht initialisieren lassen.
eieiei. Ich würde dir mal zu einem guten C Buch raten. ;)
Michael Buesch schrieb:> eieiei. Ich würde dir mal zu einem guten C Buch raten. ;)
Wär wohl mal wieder nötig ;-). Denn meine einzige gute C-Einführung als
Buch ist das K&R Original. Das originale Original wohlgemerkt. Da gehts
wirklich nicht.
A. K. schrieb:> Michael Buesch schrieb:>>> eieiei. Ich würde dir mal zu einem guten C Buch raten. ;)>> Wär wohl mal wieder nötig ;-). Denn meine einzige gute C-Einführung als> Buch ist das K&R Original. Das originale Original wohlgemerkt. Da gehts> wirklich nicht.
Wir haben mittlerweile ein neues Jahrtausend :P
Michael Buesch schrieb:> Wir haben mittlerweile ein neues Jahrtausend :P
C auch? Mein letzter Stand ist, dass es auch in aktualisierter Version
noch vom letzten Jahrtausend stammt, wenn auch knapp.
A. K. schrieb:> Michael Buesch schrieb:>>> Wir haben mittlerweile ein neues Jahrtausend :P>> C auch? Mein letzter Stand ist, dass es auch in aktualisierter Version> noch vom letzten Jahrtausend stammt, wenn auch knapp.
Ich denke du weißt, dass ich das nicht ganz so gemeint habe wie es dort
stand. ;)
Wer heute noch nach K&R schreibt hat aber trotzdem so etwa 30 Jahre
Entwicklung verschlafen/ignoriert.
Micha schrieb:> Vielen Danke an alle !!> Mit der Methode:> strncpy(mode,"Hallo",sizeof(mode));>> hat es funktioniert !>> Gruß Micha
Ich hoffe du bist dir über das schon genannte NUL-terminator Problem
damit bewusst.
If the length of from is more than size, then strncpy copies
5
just the first size characters. Note that in this case there is
6
no null terminator written into to.
Das muss in deinem Fall kein Problem sein. Man muss diesen Sonderfall
nur kennen und entsprechend reagieren. Wenn strncpy für Benutzereingaben
verwendet wird ist es sehr wichtig das Verhalten zu kennen.
A. K. schrieb:> Michael Buesch schrieb:>>> eieiei. Ich würde dir mal zu einem guten C Buch raten. ;)>> Wär wohl mal wieder nötig ;-). Denn meine einzige gute C-Einführung als> Buch ist das K&R Original. Das originale Original wohlgemerkt. Da gehts> wirklich nicht.
Kennst Du die deutsche "Übersetzung" davon? Die wirkt so, als wäre sie
von einem Automaten angefertigt, und die Idee, Sourcecode in einer
Proportionalschrift zu setzen, ist auch eher bizarr.
Die zweite Ausgabe von Anfang der 90er hingegen ist in der Übersetzung
richtig gut ...
'Ne neuere, die C99 beschreibt, gibts aber wohl nicht, wie?
Rufus t. Firefly schrieb:> Kennst Du die deutsche "Übersetzung" davon?
Nö. Hab indes schon davon gehört, vor einiger Zeit. Könnte ein gewisser
Rufus gewesen sein, der schon damals drüber wetterte ;-). Ich hatte mir
schon früh angewöhnt, lieber im englischen Original zu lesen. Auch
angesichts von IBMs deutscher Version des technischen Handbuchs vom
PC/XT (was ist ein Einheitenverstärker?) und Motorolas Übersetzung des
68000 Manuals, die ein Freund deshalb gegen mein englisches
Zweitexemplar eintauschte.
Das mag gut sein, daß Du da was von mir gelesen hast. Ich habe beide
Ausgaben.
Davon abgesehen bevorzuge ich auch originalsprachige Literatur; in den
letzten 20 Jahren waren über 90% aller Bücher, die ich gekauft habe,
englischsprachig.
Merkwürdigerweise habe ich keinen englischen K&R. Habe ich bislang nie
drüber nachgedacht, warum.
Achja, über IBM-"Deutsch" habe ich mich auch schon gefreut. "Serielle
Zeigereinheit". Na, was ist das?
Rufus t. Firefly schrieb:> "Serielle Zeigereinheit". Na, was ist das?
Finde ich jetzt nicht so schlimm. Klingt zwar ein bischen beamtisch, ist
aber immerhin fast korrekt und sogar leidlich verständlich. Sprachlich
korrekter wäre freilich "zeigende Einheit" oder "zeigendes Gerät", aber
Einheit ist in dem Kontext andersrum auch in IBM Englisch als "unit"
recht verbreitet.
>> geht auch, ist aber möglicherweise nicht ganz so performant.
Nur fürs Archiv: so ziemlich die schlechteste Möglichkeit von
allen.
"nicht ganz so performant" ist noch beschönigend, und richtig
nett wird es, wenn irgendwann in dem zu kopierenden String
ein % steht und man nicht dran denkt, was das bewirkt.
Wieso schlägt man allen Ernstes so etwas vor, um einen
String zu kopieren?
Klaus Wachtler schrieb:> Ein Gast schrieb:>>sprintf(mode,"Hallo");>>>> geht auch, ist aber möglicherweise nicht ganz so performant.>> Nur fürs Archiv: so ziemlich die schlechteste Möglichkeit von> allen.> "nicht ganz so performant" ist noch beschönigend,
Na so langsam ist das nun auch wieder nicht. Davon abgesehen kann gcc
das sogar optimieren.
> Wieso schlägt man allen Ernstes so etwas vor, um einen> String zu kopieren?
Es hat zugegebenermaßen keinen Vorteil, aber so schlimm, wie du tust,
ist es nun auch wieder nicht.
Rolf Magnus schrieb:> Klaus Wachtler schrieb:>> Ein Gast schrieb:>>>sprintf(mode,"Hallo");>>>>>> geht auch, ist aber möglicherweise nicht ganz so performant.>>>> Nur fürs Archiv: so ziemlich die schlechteste Möglichkeit von>> allen.>> "nicht ganz so performant" ist noch beschönigend,>> Na so langsam ist das nun auch wieder nicht.
Ja und es ermöglicht ganz nebenbei schöne Formatstring-attacken, wenn
der string vom Benutzer vorgegeben werden kann.
> Davon abgesehen kann gcc das sogar optimieren.
Kann/könnte, oder tut er es wirklich in der Praxis?
Michael Buesch schrieb:> Rolf Magnus schrieb:>> Klaus Wachtler schrieb:>>> Ein Gast schrieb:>>>>sprintf(mode,"Hallo");>>>>>>>> geht auch, ist aber möglicherweise nicht ganz so performant.>>>>>> Nur fürs Archiv: so ziemlich die schlechteste Möglichkeit von>>> allen.>>> "nicht ganz so performant" ist noch beschönigend,>>>> Na so langsam ist das nun auch wieder nicht.>> Ja und es ermöglicht ganz nebenbei schöne Formatstring-attacken, wenn> der string vom Benutzer vorgegeben werden kann.
Dann hat man sprintf falsch verwendet. Vom Benutzer übergebene Strings
darf man grundsätlich niemals als Formatstring verwenden.
>> Davon abgesehen kann gcc das sogar optimieren.>> Kann/könnte, oder tut er es wirklich in der Praxis?
Er tut es in der Praxis, wobei das aber vermutlich davon abhängt, mit
welcher libc man arbeitet.
Rolf Magnus schrieb:> Er tut es in der Praxis, wobei das aber vermutlich davon abhängt, mit> welcher libc man arbeitet.
Der Compiler weiss, für welche libc er den Code übersetzt? Bei der
libgcc würde das noch angehen.
A. K. schrieb:> Rolf Magnus schrieb:>>> Er tut es in der Praxis, wobei das aber vermutlich davon abhängt, mit>> welcher libc man arbeitet.>> Der Compiler weiss, für welche libc er den Code übersetzt? Bei der> libgcc würde das noch angehen.
Mag sein, daß es von der libc unabhängig ist. Jedenfalls hat gcc die
Funktion sprintf (und so gut wie jede andere libc-Funktion) zu
Optimierungszwecken schon selbst eingebaut und ruft nur dann die
libc-Implementation auf, wenn er keine Möglichkeit für die Optimierung
findet.
Siehe auch
http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Other-Builtins.html#Other-Builtins
Rolf Magnus schrieb:> Jedenfalls hat gcc die> Funktion sprintf (und so gut wie jede andere libc-Funktion) zu> Optimierungszwecken schon selbst eingebaut und ruft nur dann die> libc-Implementation auf, wenn er keine Möglichkeit für die Optimierung> findet.
Das geht aber nur, wenn sich die C-library nicht dagegen
wehrt. Standard "Bezeichner" (da wir grad beim Thema waren...) werden
mit #defines umgebogen, damit gcc sie nicht als solche erkennt und
optimiert. Du kannst Dir ja mal die counter insurgency Attacken der
glibc in stdio2.h anschauen. Das kann man wiederum mit der Definition
des Macros _FORTIFY_SOURCE verhindern.
Gruß
Marcus
Marcus Harnisch schrieb:> Das geht aber nur, wenn sich die C-library nicht dagegen> wehrt.
Also hängt es doch, wie schon vermutet, von der libc ab.
> Standard "Bezeichner" (da wir grad beim Thema waren...) werden> mit #defines umgebogen, damit gcc sie nicht als solche erkennt und> optimiert.
Das ist aber eigentlich nicht so richtig ISO-konform.