Hat C einen String-Typ? [closed]

Lesezeit: 6 Minuten

Benutzeravatar von arielschon12
arielschön12

Ich habe vor kurzem angefangen, in C zu programmieren, von Java und Python kommend. Nun, in meinem Buch habe ich festgestellt, dass die Syntax zum Erstellen eines “Hello World” -Programms etwa so lautet:

char message[10]
strcpy(message, "Hello, world!")
printf("%s\n", message);

Nun, dieses Beispiel verwendet ein Char-Array und ich habe mich gefragt – was ist mit Strings passiert? Warum kann ich nicht einfach so einen verwenden? Vielleicht gibt es einen anderen Weg, dies zu tun?

  • C hat keine Strings.

    – Saschoalm

    5. Februar 2013 um 14:07 Uhr

  • Sie brauchen Char-Nachricht[14];

    – acraig5075

    5. Februar 2013 um 14:07 Uhr

  • Ihr strcpy wird übrigens Ihr char-Array überlaufen lassen. Sie benötigen mindestens ein Zeichenarray der Länge 14 (13 Zeichen + Null-Terminator)

    – welche

    5. Februar 2013 um 14:07 Uhr

  • @Grhm strncmp ist aus zwei Gründen die falsche Funktion, erstens ist es a cmp Funktion statt a cpy Funktion, zweitens sollten Sie verwenden strlcpy Stattdessen wird sichergestellt, dass ein Null-Terminierungsbyte verwendet wird. strncpy kann Ihnen eine nicht abgeschlossene Zeichenfolge geben.

    – welche

    5. Februar 2013 um 14:15 Uhr

  • @wich: Ich meinte strncpy – war sich dessen aber nicht bewusst strlcpy was nach einer besseren Option aussieht. Danke, ich habe heute etwas gelernt..

    – Grhm

    5. Februar 2013 um 14:18 Uhr

Benutzeravatar von dgvid
dgvid

C hat und hatte noch nie einen nativen String-Typ. Per Konvention verwendet die Sprache Arrays von char mit einem Nullzeichen beendet, dh mit '\0'. Funktionen und Makros in den Standardbibliotheken der Sprache bieten Unterstützung für die nullterminierten Zeichen-Arrays, z. Strlen iteriert über ein Array von char bis es auf a trifft '\0' Charakter u strcpy Kopien aus der Quellzeichenfolge, bis sie auf a trifft '\0'.

Die Verwendung von nullterminierten Strings in C spiegelt die Tatsache wider, dass C nur ein wenig höher als Assemblersprache sein sollte. Nullterminierte Strings wurden damals schon direkt unterstützt Assemblersprache für PDP-10 und PDP-11.

Es ist erwähnenswert, dass diese Eigenschaft von C-Strings zu einigen bösen Pufferüberlauffehlern führt, einschließlich schwerwiegender Sicherheitslücken. Wenn Sie beispielsweise vergessen, eine Zeichenfolge, die als Quellenargument an übergeben wird, mit Null zu beenden strcpykopiert die Funktion sequenzielle Bytes von dem, was sich zufällig im Speicher befindet, über das Ende der Quellzeichenfolge hinaus, bis sie zufällig auf a trifft 0wodurch möglicherweise alle wertvollen Informationen überschrieben werden, die dem Speicherort der Zielzeichenfolge im Speicher folgen.

In Ihrem Codebeispiel wird das Zeichenfolgenliteral “Hello, world!” wird in ein 14 Byte langes Array von kompiliert char. Die ersten 13 Bytes enthalten die Buchstaben, das Komma, das Leerzeichen und das Ausrufezeichen, und das letzte Byte enthält das Null-Terminatorzeichen '\0', automatisch vom Compiler für Sie hinzugefügt. Wenn Sie auf das letzte Element des Arrays zugreifen würden, würden Sie feststellen, dass es gleich ist 0. Z.B:

const char foo[] = "Hello, world!";
assert(foo[12] == '!');
assert(foo[13] == '\0');

Aber in deinem Beispiel message ist nur 10 Bytes lang. strcpy schreibt alle 14 Bytes, einschließlich des Nullterminators, in den Speicher, beginnend bei der Adresse von message. Die ersten 10 Bytes werden in den Speicher geschrieben, der auf dem Stack für zugewiesen ist message und die verbleibenden vier Bytes werden einfach an das Ende des Stacks geschrieben. Die Folgen des Schreibens dieser vier zusätzlichen Bytes auf den Stapel sind in diesem Fall schwer vorherzusagen (in diesem einfachen Beispiel schadet es möglicherweise nicht), aber in realem Code führt dies normalerweise zu beschädigten Daten oder Fehlern bei Speicherzugriffsverletzungen.

  • Eine Reihe von char das hat keine '\0'-byte darin ist kein String.

    – 12431234123412341234123

    22. Oktober 2020 um 14:20 Uhr


  • führt das Schreiben von 4 zusätzlichen Bytes zur Beschädigung der ersten 10 Bytes oder zur Beschädigung eines anderen Speicherorts (4 Bytes) auf dem Stapel? In welchem ​​​​Szenario wird ein Segmentierungsfehler anstelle einer Speicherbeschädigung ausgelöst?

    – Schatten0359

    7. März 2021 um 5:14 Uhr

Es gibt kein string eintippen C. Sie müssen Char-Arrays verwenden.

Übrigens wird Ihr Code nicht funktionieren, da die Größe des Arrays es ermöglichen sollte, dass das gesamte Array plus ein zusätzliches Null-Endzeichen hineinpasst.

Um es in den von Ihnen erwähnten Sprachen zu notieren:

Java:

String str = new String("Hello");

Python:

str = "Hello"

Sowohl Java als auch Python haben das Konzept eines “Strings”, C hat das Konzept eines “Strings” nicht. C hat Zeichen-Arrays, die “schreibgeschützt” oder manipulierbar sein können.

C:

char * str = "Hello";  // the string "Hello\0" is pointed to by the character pointer
                       // str. This "string" can not be modified (read only)

oder

char str[] = "Hello";  // the characters: 'H''e''l''l''o''\0' have been copied to the 
                       // array str. You can change them via: str[x] = 't'

Ein Zeichen-Array ist eine Folge zusammenhängender Zeichen mit einem eindeutigen Sentinel-Zeichen am Ende (normalerweise ein NULL-Terminator '\0'). Beachten Sie, dass der Sentinel-Charakter in den oben genannten Fällen automatisch für Sie angehängt wird.

In C ist ein String einfach ein Array von Zeichen, das mit einem Nullbyte endet. Also ein char* wird oft “String” ausgesprochen, wenn Sie C-Code lesen.

C unterstützt keinen erstklassigen Zeichenfolgentyp.

C++ hat std::string

C hat keinen eigenen String-Datentyp wie Java.

Nur wir können den Datentyp String in C mit einem Zeichenarray oder einem Zeichenzeiger deklarieren. Beispiel:

 char message[10]; 
 or 
 char *message;

Aber Sie müssen mindestens Folgendes angeben:

    char message[14]; 

um “Hallo, Welt!” zu kopieren. in die Nachrichtenvariable.

  • 13 : Länge des “Hello, world!”
  • 1 : für ‘\0’ Nullzeichen, das das Ende der Zeichenfolge kennzeichnet

Erstens müssen Sie das alles nicht tun. Insbesondere die strcpy ist überflüssig – Sie müssen eine Zeichenfolge nicht einfach kopieren printf es. Dein message kann mit dieser Zeichenfolge definiert werden.

Zweitens haben Sie nicht genug Platz für dieses “Hello, World!” Zeichenfolge (message muss mindestens 14 Zeichen lang sein, einschließlich des zusätzlichen Zeichens für das Null-Terminator).

Das Warum ist jedoch Geschichte. In Assembler gibt es keine Strings, nur Bytes, Wörter usw. Pascal hatte Strings, aber deswegen gab es Probleme mit der statischen Typisierung – string[20] war eine andere Art, die string[40]. Es gab sogar in den frühen Tagen Sprachen, die dieses Problem vermieden, aber das verursachte Overheads durch Indirektion und dynamische Zuordnung, was damals ein viel größeres Effizienzproblem darstellte.

C entschied sich einfach dafür, die Gemeinkosten zu vermeiden und auf sehr niedrigem Niveau zu bleiben. Strings sind Zeichen-Arrays. Arrays sind sehr eng mit Zeigern verwandt, die auf ihr erstes Element zeigen. Wenn Array-Typen zu Zeigertypen “zerfallen”, gehen die Informationen zur Puffergröße aus dem statischen Typ verloren, sodass Sie nicht die alten Probleme mit Pascal-Zeichenfolgen bekommen.

In C++ gibt es die std::string Klasse, die viele dieser Probleme vermeidet – und die Overheads für die dynamische Zuordnung hat, aber heutzutage ist uns das normalerweise egal. Und in jedem Fall std::string ist eine Bibliotheksklasse – darunter befindet sich die Behandlung von Zeichen-Arrays im C-Stil.

1412030cookie-checkHat C einen String-Typ? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy