2015-05-16 15 views
11

Ci sono due string variabili, m e n:C++: A proposito di caratteri nulli

#include <string> 

string m = "0100700\0" 
cout << m.size() << endl; // it prints: 7 

string n; 
n += "0100700" 
n += '\0'; 
cout << n.size() << endl; // it prints: 8 

supponevo che entrambi avevano 8 caratteri, ma m aveva solo 7 caratteri e n avuto 8 caratteri. Perché è così?

+0

Non è necessario il carattere null esplicito poiché è già presente. –

+0

Mi dispiace per la domanda duplicata. Da ora provo a risolvere la mia domanda cercando più attentamente. – carrot031

risposta

10

La prima cosa da notare è che std::string non ha un costruttore che può dedurre la lunghezza di una stringa letterale dall'array sottostante. Quello che ha è un costruttore che accetta uno const char* e lo considera come una stringa con terminazione nulla. In tal modo, copia i caratteri fino a quando non trova il primo \0.

Questo è il costruttore utilizzato in string m = "0100700\0";, che è il motivo per cui nel primo caso la stringa è di lunghezza 7. Si noti che non c'è altro modo per ottenere la lunghezza di un array di caratteri da un puntatore al suo primo elemento.

Nel secondo esempio, si aggiunge un carattere a un oggetto preesistente std::string di lunghezza 7. Ciò aumenta la lunghezza a 8. Se si dovesse scorrere su tutti gli elementi della stringa, si sarebbe in grado di vederlo questo ottavo elemento è '\0'.

for (auto c: n) 
    if (c == 0) std::cout << "null terminator" << std::endl; 

per inizializzare una stringa contenente '\0' caratteri, avete opzioni:

utilizzare un elenco di inizializzazione:

std::string s{'a', 'b', '\0', 'd', 'e', '\0', 'g'}; 

Construct da un contenitore o una matrice diversa usando std::string 's costruttore iteratore :

std::vector<char> v{'a', 'b', '\0', 'd', 'e', '\0', 'g'}; 
char c[] = {'a', 'b', '\0', 'd', 'e', '\0', 'g'}; 
const char* ps = "ab\0de\0g"; 

std::string s0(std::begin(v), std::end(v)); 
std::string s1(std::begin(c), std::end(c)); 
std::string s2(ps, ps + 8); 
+0

Grazie mille! Ora capisco perché succede. C'è un modo per inizializzare std :: string con una stringa che contiene caratteri null? – carrot031

+0

@ carrot031 Puoi dire ad esempio 'string s {'a', 'b', '\ 0', 'd', 'e', ​​'\ 0', 'g'};' – juanchopanza

+0

Sarebbe meglio usare il costruttore iteratore, poiché i puntatori sono validi iteratori di accesso casuale. – Puppy

8

Nel primo esempio

string m = "0100700\0"; 

La variabile string è costruito da un carattere letterale, e prende tutti i caratteri fino al primo '\0' carattere trovato.

Tuttavia, il secondo esempio mostra che è possibile aggiungere un numero arbitrario di caratteri aggiuntivi a std::string e aumentarne le dimensioni.


di rispondere alla domanda dal tuo commento:

Per inizializzare una stringa da un letterale contenente '\0' caratteri che Caino sia specificato il conteggio esplicitamente

string m("0100700\0",8); 

oppure è possibile utilizzare la funzione di costruzione utilizzando a first e last iteratore:

const char x[] = "0100700\0"; 
string m(std::begin(x),std::end(x)); 
+0

Grazie mille per la tua rapida risposta! C'è un modo intelligente per inizializzare std :: string con una stringa che contiene caratteri null? – carrot031

+0

Sembra più leggibile! Lo userò. Ho cercato di creare una libreria C++ per la creazione di archivi tar. – carrot031