una textos son palabras letra iguales con comparar comparacion como caracteres cadenas cadena buscar c++ string-literals

textos - Comparación de C++ de literales de cadena



comparar string c++ (8)

Soy un novato en C ++ (solo oldschool c). Mi hijo pidió ayuda con esto y no puedo explicarlo. Si me hubiera preguntado "cómo comparo las cadenas", le habría dicho que usara strcmp (), pero eso no es lo que me confunde. Esto es lo que preguntó:

int main() { cout << ("A"< "Z"); }

imprimirá 1

int main() { cout << ("Z"< "A"); }

también imprimirá 1, pero

int main() { cout << ("Z"< "A"); cout << ("A"< "Z"); }

luego imprimirá 10. Individualmente, ambas declaraciones cout imprimen 1, pero ejecutadas en una fila ¿obtengo una respuesta diferente?


En C ++, los resultados no están especificados. N3337 para C ++ 11.

Primero, tenemos que ver cuál es el tipo de literal de cadena.

§2.14.5

9 Los literales de cadena ordinarios y los literales de cadena UTF-8 también se denominan literales de cadena estrecha. Un literal de cadena estrecha tiene el tipo "array of n const char ", donde n es el tamaño de la cadena como se define a continuación y tiene una duración de almacenamiento estático (3.7).

Se dice que las matrices se descomponen coloquialmente en punteros.

§4.2

1 Un valor o valor de tipo "matriz de NT " o "matriz de límite desconocido de T " se puede convertir en un valor de tipo "puntero a T ". El resultado es un puntero al primer elemento de la matriz.

Dado que sus literales de cadena contienen un solo carácter, son del mismo tipo ( char[2] , incluido el carácter nulo).

Por lo tanto, se aplica el siguiente párrafo:

§5.9

2 [...]

Los punteros a objetos o funciones del mismo tipo (después de las conversiones de puntero) se pueden comparar, con un resultado definido de la siguiente manera:

[...]

- Si dos punteros p y q del mismo tipo apuntan a diferentes objetos que no son miembros del mismo objeto o elementos de la misma matriz o a diferentes funciones, o si solo uno de ellos es nulo, los resultados de p<q , p>q , p<=q , y p>=q no están especificados.

Sin especificar significa que el comportamiento depende de la implementación. Podemos ver que GCC da una advertencia sobre esto:

warning: comparison with string literal results in unspecified behaviour [-Waddress] std::cout << ("Z" < "A");

El comportamiento puede cambiar entre los compiladores o la configuración del compilador, pero en la práctica para lo que sucede, vea la answer de Wintermute.


En el comunicado:

cout << ("A"< "Z");

Ha creado 2 literales de cadena : "A" y "Z" . Estos son de tipo const char * que es un puntero a una matriz de caracteres terminada en nulo. La comparación aquí es comparar los punteros y no los valores a los que apuntan. Es esta comparación de direcciones de memoria aquí que es lo que le da la advertencia del compilador. El resultado de la comparación estará determinado por el lugar donde el compilador asignó la memoria a la cual será algo arbitrario de un compilador a otro. En este caso, parece que su compilador asigna la primera dirección de memoria al primer literal encontrado.

Al igual que en C para comparar estos literales de cadena correctamente, debe usar strcmp que hará una comparación de valores.

Sin embargo, cuando haces algo de la manera más idiomática de C ++ al hacer:

cout << (std::string("A") < std::string("Z"));

Luego obtiene la comparación adecuada de los valores, ya que ese operador de comparación está definido para std::string .


Estás comparando direcciones de memoria. Aparentemente, su compilador coloca los literales de cadena en la memoria en el orden en que los encuentra, por lo que el primero es "menor" que el segundo.

Como en el primer fragmento ve "A" primero y "Z" segundo, "A" es menor. Como ve "Z" primero en el segundo, "Z" es menor. En el último fragmento, ya tiene los literales "A" y "Z" colocados cuando el segundo comando aparece.


Estás comparando direcciones de memoria. El siguiente ejemplo explica cómo comparar 2 cadenas:

#include "stdafx.h" #include <iostream> #include <cstring> //prototype for strcmp() int _tmain(int argc, _TCHAR* argv[]) { using namespace std; cout << strcmp("A", "Z"); // will print -1 cout << strcmp("Z", "A"); // will print 1 return 0; }


Las constantes de cadena ("A" y "Z") en C ++ están representadas por el concepto C: matriz de caracteres donde el último carácter es ''/ 0''. Tales constantes deben compararse con el tipo de función strcmp ().

Si desea utilizar la comparación C ++ std :: string, debe declararla explícitamente:

cout << (std::string( "A") < "Z");


Los literales de cadena tienen una duración de almacenamiento estático. En todas estas comparaciones hay direcciones comparadas de memoria asignadas por el compilador para literales de cadena. Parece que el primer literal de cadena que encuentra el compilador se almacena en la memoria con una dirección inferior en comparación con el siguiente literal de cadena encontrado.

Así en este programa

int main() { cout << ("Z"< "A"); cout << ("A"< "Z"); }

el literal de cadena "Z" se asignó con una dirección más baja que el literal de cadena "A" porque el compilador lo encontró primero.

Tener en cuenta esa comparación

cout << ("A"< "A");

puede dar resultados diferentes dependiendo de las opciones del compilador porque el compilador puede asignar dos extensiones de memoria para los literales de cadena o usar solo una copia de los literales de cadena que son iguales.

Del estándar C ++ (literales de cadena 2.14.5)

12 La definición de implementación es si todos los literales de cadena son distintos (es decir, si están almacenados en objetos no superpuestos). El efecto de intentar modificar un literal de cadena no está definido.

Lo mismo es válido para C.


Si desea comparar cadenas reales de C ++, debe declarar cadenas de C ++:

int main() { const std::string a("A"); const std::string z("Z"); cout << (z < a) << endl; // false cout << (a < z) << endl; // true }


Una cadena representa un puntero al área de memoria. Entonces, al principio, solo compara las direcciones de memoria con dicho código

"Z"< "A"

La comparación de cadenas se realiza con funciones. Dependen de "qué tipo de cadena" tienes. Tiene cadenas de matriz de caracteres, pero en el medio también son objetos. Estos objetos tienen otras funciones de comparación. Por ejemplo, CString en MFC tiene la función Comparar pero también la función CompareNoCase.

Para sus cadenas, es mejor usar el strcmp. Si depura y entra, verá lo que hace la función: compara cada carácter de ambas cadenas y devuelve un entero si se produce la primera diferencia o cero si es lo mismo.

int result = strcmp("Z", "A");

Aquí encontrarás más código de muestra