5

Estoy empezando a hacer un programa en C++ de una tienda, pero me marca el error [Warning] multi-character character constant [-Wmultichar] en la parte que marqué con ***:

main ()
{
    int Coke, Sabritas, Pepsi, Gamesa, marca, Marinela, TRosa;
    printf ("Selecciona la marca de la cual quieres comprar un producto: \n 1: Coca Cola\n 2: Sabritas \n \n 3: Pepsi \n \n 4: Gamesa \n \n Marinela \n \n Tia Rosa \n");

    scanf ("%d", &marca);
    switch (marca) {
    ***case 'Coke':***
        printf ("Elija el producto: \n 1: Coca Cola \n \n 2: Coca Cola Light \n \n 3: Coca Cola Sin Azucar \n \n 4: Sprite \n \n 5: Fanta \n \n 6: Ciel \n \n 7: Sidral Mundet \n \n 8: Del Valle \n \n 9: Fresca \n \n 10: Fuze Tea \n");

system ("pause"); }
return 0;
}
eferion
  • 49,291
  • 5
  • 30
  • 72

3 Answers3

5

C++ oculta características oscuras y desconocidas; te has topado con una de ellas.

Literales multicarácter.

Cuando encierras entre comillas simples una cadena, el compilador lo interpreta como un número entero. El estándar de C++ hace referencia a estos valores en el apartado 5.13.3.2 (resaltado y traducción mía):

5.13.3 Literales de carácter

  1. [...]
  2. Un literal de carácter que no empiece con u8, u, U o L es un literal de carácter ordinario. Un literal de carácter ordinario que contiene un único carácter representable por la colección de caracteres de ejecución tiene tipo char, con un valor equivalente al valor numérico de la codificación de dicho carácter en la colección de caracteres de ejecución. Un literal de carácter ordinario que contiene más de un carácter es un literal multicarácter. Un literal multicarácter o un literal de carácter ordinario con un sólo carácter no representable por la colección de caracteres de ejecución, tiene soporte condicional, tiene tipo int y tiene un valor dependiente de implementación.

El compilador te avisa con una alarma (que no error) de que estás usando una característica que depende de implementación (es decir: que puede funcionar de manera diferente en otros compiladores).

¿Cómo corrijo el error?.

No es un error, porque te permite compilar (y está marcado como alarma). Pero si no quieres que te aparezca deberás dejar de usar literales multicarácter o desactivar la alarma Wmultichar en la configuración de tu compilador; depende del compilador que uses se hará de una u otra manera pero en general debería bastar con añadir -Wno-multichar como parámetro de compilación.

Otras cosas a tener en cuenta.

  • Estás programando en C++, no uses utilidades de C. Cambia tus printf y scanf por std::cin y std::cout.
  • La función main debe tener int como tipo de retorno.
  • Parece que estás confundiendo los nombres de variables con el valor introducido por el usuario; son cosas independientes. Te aconsejo usar un enumerado, asigna 1 al primer valor del mismo si quieres conservar el indizado que muestras en tu código.

Teniendo en cuenta los puntos anteriores, tu código podría quedar así:

int main()
{
    enum bebida { Coke = 1, Sabritas, Pepsi, Gamesa, Marinela, TRosa };

    std::cout << "Selecciona la marca de la cual quieres comprar un producto:\n"
                "1: Coca Cola\n"
                "2: Sabritas\n"
                "3: Pepsi\n"
                "4: Gamesa\n"
                "5: Marinela\n"
                "6: Tia Rosa \n";

    int marca;
    std::cin >> marca;

    switch (marca) {
        case Coke:
        break;
        case Sabritas:
        break;
        case Pepsi:
        break;
        case Gamesa:
        break;
        case Marinela:
        break;
        case TRosa:
        break;
    }
    return 0;
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
1

EDICION: En vista de las más que correctas objeciones indicadas por la usuaria Paula_Plus_Plus he decidido eliminar el primer párrafo y medio de mi respuesta debido a que era incorrecta.

Volviendo a la pregunta, en C++ (a diferencia de por ejemplo C#), no se puede poner en los cases cualquier tipo de variable, solo valen int o tipos convertibles (de manera inequívoca) a int como char, los que derivan de enums, etc. Para más información puedes revisar los siguientes enlaces (este último en inglés).

Entonces una manera de solucionar tu problema sería utilizar las iniciales de las variables que vas a poner en cada case, esto es, trabajar con chars. Por ejemplo, en lugar de case 'Coke': puedes poner case 'C':.

El posible problema con lo anterior es que no queda del todo claro que puede significar la C, más aún puede que también haya otra variable que empiece con la letra C y entonces nos metemos en un pequeño lío. En este caso, mi alternativa sería usar una enumeración. Más concretamente, haría lo siguiente:

enum productos_tienda { Coke = 1, Sabritas, Pepsi, etc};

De esta manera, ahora puedes escribir case Coke: y así sucesivamente con cada producto que tengas. Si desconoces sobre las enumeraciones en C++, te dejo estos dos enlaces (el primero en inglés).

Por otro lado, si bien es cierto que un warning no es lo mismo que un error, el primero indica que hay algo "extraño" en tu código o que no tiene mucho sentido para el compilador (lo que puede significar code smell); y es por eso que estoy en desacuerdo con la sugerencia de desactivar el warning que se indica en tu pregunta mediante la opción -Wno-multichar. Si bien puede haber casos concretos en los que ignorar warnings sea la mejor solución, creo que siempre se puede escribir código libre de cualquier tipo de advertencias. Es más recomendable que a la hora de compilar le indiques al compilador que sea lo más estricto posible con el código que has escrito.

Para tal fin puedes incluir como parámetros de compilación las opciones: -Wall -Wextra -pedantic, o incluso si quieres ser más "radical", puedes hacer que el compilador te marque cualquier warning como error. Usualmente la opción -Werror servirá para tal fin.

Xam
  • 834
  • 3
  • 13
  • 21
  • 2
    Incorrecto. Ni es un error (es un warning) ni se está utilizando un `string` como si fuese un `char`. El literal `'Coke'` es (por extraño que parezca) un entero. – PaperBirdMaster Mar 23 '18 at 07:07
  • 1
    @Paula_plus_plus he editado mi respuesta. Espero que ahora este mejor :) – Xam Mar 23 '18 at 13:09
0

Para usar un switch case en c++ es sencillo, solo debes de usar el menu de opciones de forma que te capture el dato correcto y abra la opcion que deseas seleccionar. En tu caso quieres guardar Coke como un parametro pero no lo estarias guardando de esa forma desde tu imprecion-captura, lo que haces en tu codigo es guardar un numero, digamo que seleccionas la cocacola que es lo que quieres igualar a coke para que te abra la primera opcion asi que para eso deberias de hacer otro switch case en donde la opcion 1 sea igual a la cadena de caracteres coke o directamente guardar esa cadena de caracteres desde tu captura de datos haciendo que el usuario la coloque directamente.

Te propongo que mejor para usar switch case en el caso de tu menu especificamente uses una estructura de numeros y asi te sera mas sencillo. Ejemplo:

main ()
{
  int op;
  printf ("Selecciona la marca de la cual quieres comprar un producto: \n 1: Coca Cola\n\n 2: Sabritas \n \n 3: Pepsi \n \n 4: Gamesa \n \n 5: Marinela \n \n 6: Tia Rosa \n");
  scanf ("%d", &op);
  switch (op)
    {
    case 1:
      printf ("Elija el producto: \n 1: Coca Cola \n \n 2: Coca Cola Light \n \n 3: Coca Cola Sin Azucar \n \n 4: Sprite \n \n 5: Fanta \n \n 6: Ciel \n \n 7: Sidral Mundet \n \n 8: Del Valle \n \n 9: Fresca \n \n 10: Fuze Tea \n");
      system ("pause");
    }
}
ASASCED
  • 1,218
  • 8
  • 27