6 Stimmen

Warum stürzt die Verwendung von strcat bei Zeichenzeigern ab?

Warum stürzt dieser Code ab? verwendet strcat illegal auf Zeichenzeigern?

#include <stdio.h>
#include <string.h>

int main()
{
   char *s1 = "Hello, ";
   char *s2 = "world!";
   char *s3 = strcat(s1, s2);
   printf("%s",s3);
   return 0;
}

Bitte geben Sie einen korrekten Weg mit Verweis auf beide Array und Zeiger.

2 Stimmen

Sie verwenden strcat falsch. Es hängt die zweite Zeichenkette an das Ende der ersten Zeichenkette an. Die Zeichenkette, die es zurückgibt, ist nur ein Hilfsmittel. Sie können eine konstante Zeichenkette (Ihr s1) nicht ändern, deshalb stürzt es ab. s1 zeigt auf schreibgeschützten Speicher.

14 Stimmen

Wenn alles in Ordnung wäre, würde der Code nicht abstürzen.

1 Stimmen

Vielleicht solltest du deine Frage überarbeiten, Ashish. Du bekommst wahrscheinlich Ablehnungen, weil du sagst "auch wenn alles in Ordnung ist". Die Frage ist aber sehr berechtigt.

12voto

James McNellis Punkte 337231

Das Problem ist, dass s1 auf ein Stringliteral zeigt und Sie versuchen, es durch Anhängen von s2 zu. Sie dürfen keine String-Literale verändern. Sie müssen ein Zeichenarray erstellen und beide Zeichenketten in dieses Array kopieren, etwa so:

char *s1 = "Hello, ";
char *s2 = "world!";

char s3[100] = ""; /* note that it must be large enough! */
strcat(s3, s1);
strcat(s3, s2);
printf("%s", s3);

"Groß genug" bedeutet mindestens strlen(s1) + strlen(s2) + 1 . Die + 1 ist die Berücksichtigung des Nullterminators.

Dennoch sollten Sie ernsthaft in Erwägung ziehen, die strncat (oder das wohl bessere, aber nicht standardisierte strlcat (falls verfügbar), die auf Einhaltung der Grenzen geprüft werden und daher weit besser sind als strcat .

0 Stimmen

Arrays mit variabler Länge (c99) oder alles unter 100! :P

0 Stimmen

Der Grund, warum strcat sein erstes Argument zurückgibt, ist eine Bequemlichkeit für Situationen wie diese - es bedeutet, dass Sie die Verkettung in einer Zeile durchführen können: strcat(strcat(s3, s1), s2);

0 Stimmen

Ich würde snprintf in fast allen Fällen dieser Art gegenüber strncat vorziehen. Es ist ein kleiner Leistungseinbruch, aber es ist wahrscheinlicher, dass es korrekt verwendet wird, da die korrekte Verwendung von strncat nicht mit dem Rest der Bibliothek vereinbar ist. (Das 'n' bedeutet etwas anderes, als die Leute zu denken scheinen.)

1voto

penguin4hire Punkte 268

Der richtige Weg wäre in diesem Fall, in der Zielzeichenkette (s1) genügend Platz für 6 zusätzliche Zeichen (s2) sowie den Nullterminator für die Zeichenkette zu reservieren.

char s1[14] = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);
printf("%s",s3);

0voto

Opera Punkte 963

Hier ein Zitat aus dem strcat()-Handbuch: "Die Funktion strcat() hängt den src-String an den dest-String an und überschreibt dabei das Null-Byte (' \0 ') am Ende von dest und fügt dann ein abschließendes Null-Byte hinzu. Die Zeichenketten dürfen sich nicht überlappen, und die Zeichenkette dest muss genügend Platz für das Ergebnis haben."

Das Problem dabei ist, dass s1 und s2 auf statische Strings verweisen, die "read only" sind. Wenn Sie also versuchen, eine strcat-Operation mit einem solchen String in den dest-Parametern durchzuführen, erhalten Sie einen Fehler.

Am besten erstellen Sie Ihre Hallo-Welt-Zeichenkette hier, indem Sie sie malloc, damit sie sowohl s1 als auch s2 enthalten kann. Vergessen Sie auch nicht, ein ' \n ' am Ende Ihres printf-Formatstrings, sonst könnten Sie überrascht werden.

Hier ist der Code, den ich an Ihrer Stelle schreiben würde:

int main()
{
  char* s1 = "Hello ";
  char* s2 = "World !";
  char *s3 = malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char));
/* +1 is for the null terminating character
and sizeof(*s3) is the actual size of a char. */

  if (s3)
  {
    strcat(s3, s1);
    strcat(s3, s2);
    printf("%s\n", s3);
    free(s3); // always free what you alloc when you don't need it anymore.
  }
  return 0;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X