Gast
#1941927
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 !
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
|
Anzeige
|
Kann keinen String zuweisen wieso ?
Gast
#1941927
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 !
Gast
#1941930
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) );
Gast
#1941932
Das geht so:
oder besser:
Damit stellst du sicher, nicht über die Arraygrenzen hinauszuschreiben.
Gast
#1941936
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);
Gast
#1941940
geht auch, ist aber möglicherweise nicht ganz so performant.
Gast
#1941946
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.
Gast
#1941955
[c]
char mode[7] = {0};
switch(test)
{
case 0: strncpy( mode, "Hallo", sizeof( mode ) -1 ); break;
case 1: strncpy( mode, "Hallo", sizeof( mode ) -1 ); break;
}
sprintf(msg, "Test: %s", mode);
[\]
so jetzt aber sollte es sauber sein.
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.
Gast
#1941969
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. Peter schrieb: > das glaube ich nun nicht, weil es {0} meines wissen den completten > string mit \0 anlegt. Hmm. Stimmt. Funktionieren sollte es auch mit sprintf. Hast Du #include <stdio.h> und das Einbinden der Bibliothken beim Linker berücksichtigt? 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.
Gast
#1942176
Vielen Danke an alle !! Mit der Methode: strncpy(mode,"Hallo",sizeof(mode)); hat es funktioniert ! Gruß Micha 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.
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.
Gast
#1942325
Warum überhaupt den String buchstabenweise kopieren, wenn er später sowieso mit sprintf nochmal umkopiert wird? Wie wärs mit der Lösung:
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. Ein Gast schrieb: >
> > 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?
Gast
#1942844
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?
Gast
#1943402
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.
Gast
#1943484
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
Gast
#1944520
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. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|