A documentação está correta. Use c_str()
se quiser uma string terminada em nulo.
Se os implementadores começaram a implementar data()
em termos de c_str()
você não precisa se preocupar, ainda use data()
se não precisar que a string seja terminada em nulo, em algumas implementações pode acabar tendo um desempenho melhor do que c_str ().
strings não precisam necessariamente ser compostas de dados de caracteres, elas podem ser compostas com elementos de qualquer tipo. Nesses casos, data()
é mais significativo. c_str()
na minha opinião, só é realmente útil quando os elementos de sua string são baseados em caracteres.
Extra : no C ++ 11 em diante, ambas as funções devem ser as mesmas. ou data
seja, agora é necessário ter terminação nula. De acordo com cppreference : "O array retornado é terminado em nulo, ou seja, data () e c_str () executam a mesma função."
.data()
, portanto, eles não são mais equivalentes para strings não constantes.Em C ++ 11 / C ++ 0x ,
data()
ec_str()
não é mais diferente. E, portanto, tambémdata()
é necessário ter uma terminação nula no final.fonte
std::string
aloque um extrachar
para um rastreamento'\0'
. Quando você fizer issostd::string s("\0");
, amboss.data()[0]
es.data()[1]
Mesmo sabendo que você viu que eles fazem o mesmo, ou que .data () chama .c_str (), não é correto assumir que esse será o caso para outros compiladores. Também é possível que seu compilador mude com uma versão futura.
2 razões para usar std :: string:
std :: string pode ser usado para texto e dados binários arbitrários.
Você deve usar o método .c_str () quando estiver usando sua string como exemplo 1.
Você deve usar o método .data () quando estiver usando sua string como exemplo 2. Não porque seja perigoso usar .c_str () nesses casos, mas porque é mais explícito que você está trabalhando com dados binários para outros revisarem seu código.
Possível armadilha com o uso de .data ()
O código a seguir está errado e pode causar um segfault em seu programa:
Por que é comum que os implementadores façam .data () e .c_str () fazerem a mesma coisa?
Porque é mais eficiente fazer isso. A única maneira de fazer .data () retornar algo que não seja terminado em nulo, seria ter .c_str () ou .data () copiar seu buffer interno, ou usar apenas 2 buffers. Ter um único buffer terminado em null sempre significa que você sempre pode usar apenas um buffer interno ao implementar std :: string.
fonte
Já foi respondido, algumas notas sobre o objetivo: Liberdade de implementação.
std::string
operações - por exemplo, iteração, concatenação e mutação de elemento - não precisam do terminador zero. A menos que você passe ostring
para uma função que espera uma string terminada em zero, ele pode ser omitido.Isso permitiria que uma implementação tivesse substrings compartilhando os dados reais da string:
string::substr
poderia conter internamente uma referência aos dados da string compartilhada e o intervalo inicial / final, evitando a cópia (e alocação adicional) dos dados reais da string. A implementação iria adiar a cópia até que você chame c_str ou modifique qualquer uma das strings. Nenhuma cópia jamais seria feita se os strigns envolvidos fossem apenas lidos.(a implementação copy-on-write não é muito divertida em ambientes multithread, além da economia típica de memória / alocação não compensar o código mais complexo de hoje, então raramente é feito).
Da mesma forma,
string::data
permite uma representação interna diferente, por exemplo, uma corda (lista vinculada de segmentos de corda). Isso pode melhorar significativamente as operações de inserção / substituição. novamente, a lista de segmentos teria que ser reduzida a um único segmento quando você chamarc_str
oudata
.fonte
Citação de
ANSI ISO IEC 14882 2003
(C ++ 03 Standard):fonte
Todos os comentários anteriores são consistentes, mas eu também gostaria de adicionar que começando em c ++ 17, str.data () retorna um char * em vez de const char *
fonte
const
enon-const
sobrecargas estão disponíveis desde C ++ 17.