Tengo un struct:

typedef struct entry {
char *surname;
int house_no;
char *postcode;
} BEntry;

y una función para convertir cadenas a mayúsculas:

void toUpper(char *str){
    while (*str != '\0')
    {
        *str = toupper(*str);
        str++;
    }
}

y en mi principal función de asignar valores a los miembros de una estructura y desea convertir el apellido en mayúsculas:

mentry->surname = "bob";
mentry->house_no = 17;
mentry->postcode = "GK116BY";
toUpper(me->surname);

¿Cuál es la forma correcta para convertir una cadena a mayúsculas por el paso de un tipo de puntero a una función como esta? Mi programa es devolver un fallo de segmentación. Cualquier ayuda es muy apreciada, gracias.

  • Lo que está mal con lo que tienes?
  • "bob" es un literal de cadena presente en lectura única ubicación. Usted no puede modificarlo. Copia y, a continuación, modifique.
  • El problema es que la asignación de "bob — una constante de cadena — de surname que es de tipo char*. Usted debe por lo menos tienen una advertencia de que esto es ignorar const’ness en la asignación. Siempre uso completo de las advertencias. Una forma de resolverlo es mediante la ejecución de char * strdup(const char s) como parte de la misión. Usted, a continuación, obtener ` char *` que usted puede modificar. No olvides que para liberar la memoria cuando usted está a través.
InformationsquelleAutor Highway62 | 2014-11-06

3 Comentarios

  1. 3

    Su toUpper() aplicación debería funcionar bien. Sin embargo, se debe prestar atención a las advertencias del compilador (o subir los niveles de advertencia si no … debería ver algo cuando assigne un literal de cadena a un char * así). Los literales de cadena son const, es decir, no se pueden modificar. Cuando intenta escribir para ellos, esto hará que el fallo de segmentación que usted está viendo.

    Necesita algo como:

    mentry->surname = malloc(4);
    strcpy(mentry->surname, "bob");

    o la más conveniente, pero no es parte del estándar de C forma:

    mentry->surname = strdup("bob");

    Y, por supuesto, asegúrese de llamar free() más tarde, de cualquier manera.

    • Los literales de cadena no son const en C. yo creo que está mal de la norma para definir de esa manera, pero lamentablemente es así. Así que OP no recibirá una advertencia. En gcc puede forzar advertencias para que se caso con -Wwrite-strings, en caso de que el programa viola la norma, pero en mi humilde opinión es mejor de esta manera.
    • Estaba seguro de que eran pero me echó un vistazo y estás absolutamente en lo correcto. Es decir la modificación de ellos es un comportamiento indefinido, lo cual plantea la pregunta de por qué no… pero sí, por lo que no hay una clara advertencia a partir de este entonces.
  2. 1

    Literales de cadena como "Hello, World!" no son modificables. Bien duplicar el literal de cadena:

    hw = strdup("Hello, World!");

    o declarar una char[] variable y se inicializa a un literal de cadena. Como un caso especial, los literales de cadena se utiliza de esta manera son modificables:

    char hw[] = "Hello, World!";
    • Literales no son modificables, también en el 2º caso que muestran no es el literal que va a ser de escritura, pero el contenido de hw.
    • Eso es porque no es un literal; sé. Escribí la respuesta en este ligeramente de modo incorrecto, porque es menos complicado formular y más fácil de entender que la versión correcta.
    • En ambos casos "Hello, World!" se un literal. En ambos casos se trata de no de escritura.
    • Técnicamente sí, pero es un caso especial en el que el contenido de la literal de cadena son implícitamente la inicialización de la matriz (cf. ISO 9899:2011§6.7.9.14). Podría ver esto como si la cadena literal en realidad era escritura de una programadores perspectiva. Sé que no es muy correcto, pero más fácil de entender.
  3. 1

    La manera más fácil de convertir char * a minúsculas o mayúsculas en c, es mediante el uso de strdup

    #include <string.h>
    
    char    *to_uppercase(char *s)
    {
        int i = 0;
        char    *str = strdup(s);
    
        while (str[i])
        {
            if (str[i] >= 97 && str[i] <= 122)
                str[i] -= 32;
            i++;
        }
        return (str);
    }

Dejar respuesta

Please enter your comment!
Please enter your name here