2010-08-30 10 views
5

Me gustaría comparar un literal de carácter con el primer elemento de cadena, para comprobar si hay comentarios en un archivo. ¿Por qué usar un char? Quiero hacer de esto una función que acepte un carácter var para el comentario. No quiero permitir una cadena porque quiero limitarla a un solo carácter de longitud.Comparación de Literal de carácter a Std :: String en C++

Con esto en mente, asumí que el camino más fácil sería abordar el personaje y pasarlo a la función de comparación std :: string. Sin embargo, esto me está dando resultados no deseados.

Mi código es el siguiente:

#include <string> 
#include <iostream> 

int main (int argc, char *argv[]) 
{ 
    std::string my_string = "bob"; 
    char my_char1 = 'a'; 
    char my_char2 = 'b'; 

    std::cout << "STRING : " << my_string.substr(0,1) << std::endl 
     << "CHAR : " << my_char1 << std::endl; 
    if (my_string.substr(0,1).compare(&my_char1)==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 

    std::cout << "STRING : " << my_string.substr(0,1) << std::endl 
     << "CHAR : " << my_char2 << std::endl; 
    if (my_string.substr(0,1).compare(&my_char2)==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 

    std::cout << "STRING : " << my_string << std::endl 
     << "STRING 2 : " << "bob" << std::endl; 
    if (my_string.compare("bob")==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 
} 

me da ...

STRING : b 
CHAR : a 
NOPE... 
STRING : b 
CHAR : b 
NOPE... 
STRING : bob 
STRING 2 : bob 
WOW! 

¿Por qué piensan que la función de la sub-cadena y el carácter no son los mismos. ¿Cuál es la forma más corta de comparar correctamente chars y std :: string vars?

(una breve diatriba a reclasificación evitar de mi pregunta .... puede saltarse)
cuando digo que quiero decir más corto que de un deseo de la elocuencia de codificación. Tenga en cuenta que esta NO es una pregunta para la tarea. Soy un candidato Ph.D de ingeniería química y estoy codificando como parte de una investigación independiente. Una de mis últimas preguntas fue reclasificada como "tarea" por el usuario msw (quien también hizo una observación sarcástica) cuando le pregunté sobre la eficiencia, que consideré al borde del abuso. Mi código puede o no ser reutilizado por otros, pero estoy tratando de que sea fácil de leer y mantener. También tengo un extraño deseo de hacer que mi código sea lo más eficiente posible siempre que sea posible. De ahí las preguntas sobre eficiencia y elocuencia.

Respuesta

14

Hacer esto:

if (my_string.substr(0,1).compare(&my_char2)==0) 

no funcionará porque estás "engañar" la cuerda en pensar que está obteniendo un puntero a una C-string terminada en nulo. Esto tendrá efectos extraños hasta e incluso bloqueando su programa. En su lugar, sólo tiene que utilizar la igualdad normales para comparar el primer carácter de la cadena con my_char:

if (my_string[0] == my_char) 
    // do stuff 
+5

Y no olvide comprobar que '0

3

Usted puede utilizar el operador [] de la cadena para compararlo con un solo carbón

// string::operator[] 
#include <iostream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string str ("Test string"); 
    int i; char c = 't'; 
    for (i=0; i < str.length(); i++) 
    { 
     if (c == str[i]) { 
      std::cout << "Equal at position i = " << i << std::endl; 
     } 
    } 
    return 0; 
} 
1

El comportamiento de las dos primeras llamadas para comparar depende totalmente de lo contenido de la memoria al azar sigue la dirección de cada carbón. Está llamando al basic_string::compare(const char*) y se supone que el parámetro es un C-String (nulo), ni un solo carácter. La llamada a compare() comparará su char deseado, seguido de todo en la memoria después de ese char hasta el siguiente byte de 0x00, con std :: string en la mano.

Otoh < < operador tiene una sobrecarga adecuada para la entrada de char, por lo que su salida no refleja lo que está comparando aquí.

Convierte las declas de yb en const char[] a = "a"; y obtendrás lo que quieres que suceda.

4

¿Por qué no usar simplemente el operador de indexación en la cadena? Devolverá un tipo de carácter.

if (my_string[0] == my_char1) 
1

Bastante estándar, las cadenas en C++ son nulas; los personajes no sonEntonces, al usar el método de comparación estándar, realmente está comprobando si "b \ 0" == 'b'.

he usado esto y tiene la salida deseada:

if (my_string.substr(0,1).compare(0, 1, &my_char2, 1)==0) 
    std::cout << "WOW!" << std::endl; 
else 
    std::cout << "NOPE..." << std::endl; 

Lo que esto quiere decir es empezar en la posición 0 de la subcadena, utilice una longitud de 1, y compararlo con mi referencia caracteres con una longitud de 1. Reference

+1

Las cadenas en C++ NO tienen terminación nula. Están terminados en nulo en C, porque en realidad son un puntero a char. –

+0

@Draco: 'std :: string' no es necesario que tenga terminación nula (aunque eso está cambiando en 0x), pero todavía hay muchos lugares en el estándar C++ que asume una matriz de caracteres terminados en nulo. Incluyendo una cantidad de métodos dentro de 'std :: string', como ilustra esta pregunta. –

Cuestiones relacionadas