variable usar resueltos lenguaje funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c++ c stl string c-strings

resueltos - ¿Por qué usar c cadenas en c++?



funciones de cadenas de caracteres en c++ (18)

¿Hay alguna buena razón para usar C-strings en C ++ hoy en día? Mi libro de texto los usa en ejemplos en algunos puntos, y realmente siento que sería más fácil simplemente usar una std :: string.


¿Porque es así como provienen de numerosas API / bibliotecas?


1) "constante de cadena" es una cadena C (const char *), convirtiéndola a const std :: string & es un proceso en tiempo de ejecución, no necesariamente simple u optimizado. 2) La biblioteca de fstream usa cadenas tipo c para pasar nombres de archivos.

Mi regla de oro es pasar const std :: string y si estoy a punto de usar los datos como std :: string de todos modos (por ejemplo, cuando los almaceno en un vector), y const char * en otros casos.


Algunos mensajes mencionan problemas de memoria. Esa podría ser una buena razón para rechazar std :: string, pero char * probablemente no sea el mejor reemplazo. Todavía es un idioma OO. Tu propia clase de cuerda es probablemente mejor que un char *. Incluso puede ser más eficiente: puede aplicar Small String Optimization, por ejemplo.

En mi caso, estaba tratando de obtener aproximadamente 1GB de cadenas de un archivo de 2GB, rellenarlas en registros con aproximadamente 60 campos y luego ordenarlos 7 veces en diferentes campos. El código de mis predecesores tomó 25 horas con char *, mi código se ejecutó en 1 hora.


Código heredado que no conoce std :: string. Además, antes de C ++ 11, la apertura de archivos con std :: ifstream o std :: ofstream solo era posible con const char * como entrada al nombre del archivo.


Control de memoria Recientemente tuve que manejar cadenas (en realidad blobs de una base de datos) de aproximadamente 200-300 MB de tamaño, en una aplicación de subprocesamiento masivo. Era una situación en la que solo una copia más de la cadena podría haber reventado el espacio de direcciones de 32 bits. Tenía que saber exactamente cuántas copias de la cadena existían. Aunque soy un evangelista de STL, utilicé char * porque me dio la garantía de que no se asignó memoria adicional ni copia adicional. Sabía exactamente cuánto espacio necesitaría.

Aparte de eso, el procesamiento de cadenas STL estándar se pierde en algunas funciones C grandes para el procesamiento / análisis de cadenas. Afortunadamente, std :: string tiene el método c_str () para const acceso al buffer interno. Para usar printf () todavía tienes que usar char * (qué idea tan loca del equipo de C ++ es que no incluye (n) la funcionalidad printf, una de las funciones más útiles SIEMPRE en C. Espero que el formato boost :: pronto será incluido en el STL.


Dada la elección, generalmente no hay ninguna razón para elegir cadenas primitivas de C ( char* ) sobre cadenas de C ++ ( std::string ). Sin embargo, a menudo no tiene el lujo de elegir. Por ejemplo, los constructores de std::fstream toman cadenas C, por razones históricas. Además, las bibliotecas C (¡lo has adivinado!) Usan cadenas C.

En su propio código C ++, es mejor usar std::string y extraer la cadena C del objeto según sea necesario utilizando la función c_str() de std::string .


Depende de las bibliotecas que estás usando. Por ejemplo, cuando se trabaja con MFC , a menudo es más fácil usar CString cuando se trabaja con varias partes de la API de Windows. También parece funcionar mejor que std :: string en aplicaciones Win32.

Sin embargo, std :: string es parte del estándar de C ++, por lo que si desea una mejor portabilidad, vaya con std :: string.


Después de pasar mucho, mucho, demasiado tiempo depurando reglas de inicialización y cada implementación de cadena concebible en varias plataformas requerimos cadenas estáticas para ser const char *.

Después de pasar mucho, mucho, demasiado tiempo depurando el código de char * malo y pérdidas de memoria, sugiero que todas las cadenas no estáticas sean algún tipo de objeto de cadena ... hasta que el perfilado demuestre que puede y debe hacer algo mejor ;-)


Digamos que tiene algunas constantes de cadena en su código, que es una necesidad bastante común. Es mejor definirlos como cadenas C que como objetos C ++, más livianos, portátiles, etc. Ahora, si va a pasar estas cadenas a varias funciones, es bueno si estas funciones aceptan una cadena C en lugar de requerir un Objeto de cadena C ++.

Por supuesto, si las cadenas son mutables, entonces es mucho más conveniente usar objetos de cadenas C ++.


La razón habitual para hacerlo es que le gusta escribir desbordamientos de búfer en el manejo de cadenas. Las cadenas contadas son tan superiores a las cadenas terminadas que es difícil ver por qué los diseñadores de C alguna vez usaron cadenas terminadas. Fue una mala decisión entonces; es una mala decisión ahora.


Las únicas razones por las que he tenido que usarlas es cuando me comunico con bibliotecas de terceros que usan cadenas de estilo C. También podría haber situaciones esotéricas en las que usaría cadenas de estilo C por motivos de rendimiento, pero la mayoría de las veces, el uso de métodos en cadenas de C ++ es probablemente más rápido debido a la incorporación y especialización, etc.

Puede usar el método c_str() en muchos casos cuando trabaja con ese tipo de API, pero debe tener en cuenta que el carácter * devuelto es const, y no debe modificar la cadena mediante ese puntero. En ese tipo de situaciones, puede utilizar un vector <char> en su lugar, y al menos obtener el beneficio de una administración de memoria más sencilla.


Las cadenas STL son mucho más fáciles de usar y no veo ninguna razón para no usarlas.

Si necesita interactuar con una biblioteca que solo toma cadenas tipo C como argumentos, siempre puede llamar al método c_str () de la clase de cadena.


Las cadenas c no tienen el costo de ser una clase.

Por lo general, las cadenas c pueden dar como resultado un código más rápido, ya que están más cerca del nivel de la máquina

Esto no quiere decir que no puedas escribir un código incorrecto con ellos. Pueden ser mal utilizados, como cualquier otra construcción.

Hay una gran cantidad de llamadas a la biblioteca que los exigen por razones históricas.

Aprende a usar cadenas de caracteres y stl strings, y usa cada una cuando tenga sentido hacerlo.


Los libros de texto tienen cadenas de caracteres de la vieja escuela porque muchas funciones básicas todavía los esperan como argumentos o los devuelven. Además, da una idea de la estructura subyacente de la cadena en la memoria.


Para aplicaciones como la mayoría de las plataformas integradas, donde no tiene el lujo de un montón para almacenar las cadenas que se manipulan, y donde se requiere la asignación previa determinista de almacenamientos intermedios de cadenas.


Si el código de C ++ es "profundo" (cerca del kernel, que depende en gran medida de las bibliotecas de C, etc.) es posible que desee utilizar C cadenas de manera explícita para evitar muchas conversiones dentro y fuera de std :: string. De, si está interactuando con otros dominios de lenguaje (Python, Ruby, etc.) puede hacerlo por la misma razón. De lo contrario, use std :: string.


Si una función necesita una cadena constante , todavía prefiero usar ''const char *'' (o const wchar_t *) incluso si el programa usa std :: string, CString, EString o lo que sea.

Hay demasiadas fuentes de cadenas en una gran base de código para asegurarse de que la persona que llama tendrá la cadena como std :: string y ''const char *'' es el mínimo común denominador.


Un par más de notas de control de memoria:

Las cadenas C son tipos POD, por lo que se pueden asignar en el segmento de datos de solo lectura de la aplicación. Si declara y define std::string constantes std::string en el ámbito del espacio de nombres, el compilador generará un código adicional que se ejecutará antes de que main() invoque el constructor std::string para cada constante. Si su aplicación tiene muchas cadenas constantes (por ejemplo, si ha generado código C ++ que utiliza cadenas constantes), las cadenas C pueden ser preferibles en esta situación.

Algunas implementaciones de std::string admiten una característica llamada SSO ("optimización de cadena corta" o "optimización de cadena pequeña") donde la clase std::string contiene almacenamiento para cadenas de hasta cierta longitud. Esto aumenta el tamaño de std::string pero a menudo reduce significativamente la frecuencia de asignaciones / desasignaciones de tiendas libres, mejorando el rendimiento. Si su implementación de std::string no es compatible con SSO, la construcción de una std::string vacía en la pila aún realizará una asignación de almacenamiento gratuito. Si ese es el caso, usar cadenas C asignadas a la pila temporal puede ser útil para el código de rendimiento crítico que usa cadenas. Por supuesto, debes tener cuidado de no dispararse en el pie cuando hagas esto.