strncpy entspricht für std :: string?

7

Gibt es in der C ++ - Standardbibliothek eine genaue Entsprechung zu strncpy ? Ich meine eine Funktion, die eine Zeichenfolge von einem Puffer zu einem anderen kopiert, bis es die abschließende 0 trifft? Zum Beispiel, wenn ich Strings von einer unsicheren Quelle, wie zum Beispiel TCP-Paketen, analysieren muss, kann ich die Länge überprüfen, während ich mit den Daten fertig werde.

Ich habe bereits viel zu diesem Thema gesucht und auch einige interessante Themen gefunden, aber alle diese Leute waren glücklich mit std :: string :: assign, das auch eine Größe von Zeichen als Parameter kopieren kann . Mein Problem mit dieser Funktion ist, dass es keine Überprüfungen durchführt, wenn eine abschließende Null bereits getroffen wurde - es nimmt die gegebene Größe ernst und kopiert die Daten genau wie memcpy es in den Puffer der Zeichenfolge tun würde . Auf diese Weise wird viel mehr Speicher zugewiesen und kopiert, als wenn es eine solche Überprüfung während der Bewältigung gäbe.

Das ist die Art und Weise, wie ich dieses Problem derzeit umgebe, aber es gibt einige Gemeinkosten, die ich vermeiden möchte:

%Vor%

Dieser Codeabschnitt ist Teil meines Parsers für PE-Binärdateien (der Routine, die die Exporttabelle parst, um genau zu sein). rva2sra konvertiert eine relative virtuelle Adresse in eine relative Adresse des PE-Abschnitts. Die Struktur ExportDirectory_t enthält die RVA für den Exportnamen der Binärdatei. sollte eine mit Null abgeschlossene Zeichenfolge sein. Aber das muss nicht immer der Fall sein - wenn jemand es möchte, könnte es die abschließende Null weglassen, die mein Programm in den Speicher laufen lassen würde, der nicht zu der Sektion gehört, wo es schließlich abstürzen würde ( im besten Fall ...).

Es wäre kein großes Problem, eine solche Funktion selbst zu implementieren, aber ich würde es bevorzugen, wenn es eine Lösung dafür in der C ++ - Standardbibliothek implementieren würde.

    
athre0z 16.01.2012, 19:29
quelle

7 Antworten

11

Wenn Sie wissen, dass der Puffer, aus dem Sie string machen möchten, mindestens eine NUL enthält, können Sie sie einfach an den Konstruktor übergeben:

%Vor%

Wenn Sie nicht sicher sind , müssen Sie nur nach der ersten Null suchen und den Konstruktor von string anweisen, eine Kopie dieser Daten zu erstellen:

%Vor%

Sie können die zweite Version (die immer funktioniert, auch wenn es keine NUL im Puffer gibt) in eine kleine Funktion umwandeln:

%Vor%

Aber eine Sache ist zu beachten: Wenn Sie dem Konstruktor mit einem Argument einen eigenen Wert für const char* übergeben, wird er so lange ausgeführt, bis ein NUL gefunden wird. Es ist wichtig, dass Sie wissen, dass mindestens ein NUL im Puffer vorhanden ist, wenn Sie den Konstruktor mit einem Argument von std::string verwenden.

Leider (oder glücklicherweise) gibt es kein perfektes Äquivalent von strncpy für std::string .

    
Seth Carnegie 16.01.2012, 19:46
quelle
3

Die Klasse std::string in AWL kann Nullzeichen innerhalb der Zeichenfolge enthalten ( "xxxstrncpyyyy" ist eine vollständig gültige Zeichenfolge der Länge 7). Das bedeutet, dass nichts über Null-Terminierung bekannt ist (naja, es gibt Konvertierungen von / zu C-Strings). Mit anderen Worten, es gibt keine Alternative in der AWL für %code% .

Es gibt einige Möglichkeiten, Ihr Ziel mit einem kürzeren Code zu erreichen:

%Vor%

oder

%Vor%     
Karel Petranek 16.01.2012 19:50
quelle
3
  

Gibt es ein genaues Äquivalent zu strncpy in der C ++ - Standardbibliothek?

Ich hoffe natürlich nicht!

  

Ich meine eine Funktion, die eine Zeichenfolge von einem Puffer zu einem anderen kopiert, bis es die abschließende 0 trifft?

Ah, aber das ist nicht das, was strncpy() tut - oder zumindest ist es nicht alles .

strncpy() lässt Sie die Größe n des Zielpuffers angeben und kopiert maximal n -Zeichen. Soweit ist es in Ordnung. Wenn die Länge der Quellzeichenfolge ("Länge" definiert als die Anzahl der Zeichen vor dem abschließenden 'n' ) n' überschreitet, wird der Zielpuffer mit zusätzlichen 'strncpy()' s aufgefüllt, was selten nützlich ist. Und wenn die Länge, wenn die Quellzeichenfolge strcpy() überschreitet, wird das abschließende strncpy() nicht kopiert .

Die strncat() -Funktion wurde für die Art und Weise entwickelt, in der frühe Unix-Systeme Dateinamen in Verzeichniseinträgen speicherten: als 14-Byte-Puffer fester Größe, der bis zu 14 Zeichen lang sein kann. (EDIT: Ich bin mir nicht 100% sicher, dass das die eigentliche Motivation für sein Design war.) Es ist wohl keine String-Funktion, und es ist nicht nur eine "sicherere" Variante von ''std::string'' .

Sie können das Äquivalent von dem erreichen, was man annehmen könnte %code% (mit dem Namen) mit %code% :

%Vor%

Dies wird immer %code% -terminiert den Zielpuffer, und es wird nicht unnötig mit zusätzlichen %code% Bytes auffüllen.

Suchen Sie wirklich nach einem %code% Äquivalent?

BEARBEITEN: Nachdem ich das oben geschrieben habe, habe ich diese Tirade auf meinem Blog.

    
Keith Thompson 16.01.2012 20:14
quelle
1

Verwenden Sie den Konstruktor der Klasse:

%Vor%

Dies ergibt eine exakte Kopie gemäß dieser Dokumentation: Ссылка

    
user529758 16.01.2012 19:32
quelle
1

std :: string hat einen Konstruktor mit der nächsten Signatur, der verwendet werden kann:

> %Vor%

mit nächster Beschreibung:

  

Der Inhalt wird mit einer Kopie der Zeichenkette initialisiert, die durch die ersten n Zeichen in dem Array von Zeichen gebildet wird, auf die s zeigt.

    
BЈовић 16.01.2012 19:39
quelle
1

Der Teilzeichenfolgekonstruktor der Zeichenkette kann tun, was Sie wollen, obwohl es kein exaktes Äquivalent zu strncpy ist (siehe meine Notizen am Ende):

%Vor%
  

Konstruiert den String mit einem Teilstring [pos, pos + count] von anderem. Wenn count == npos oder wenn der angeforderte Teilstring nach dem Ende des Strings andauert, ist der resultierende Teilstring [pos, size ()).

Quelle: Ссылка

Beispiel:

%Vor%

Ausgabe:

%Vor%

Unterschiede zu strncpy:

  • Der Zeichenfolgenkonstruktor hängt immer ein Nullzeichen an das Ergebnis, strncpy nicht;
  • Der Zeichenfolgenkonstruktor puffert das Ergebnis nicht mit 0s, wenn ein nullbeendendes Zeichen vor der angeforderten Anzahl erreicht wird, strncpy.
Julien-L 27.09.2016 01:05
quelle
0

Es gibt kein integriertes Äquivalent. Sie müssen Ihre eigene strncpy rollen.

%Vor%     
Steve Ward 06.08.2014 05:59
quelle

Tags und Links