C++ spanish question mark

后端 未结 6 1544
梦谈多话
梦谈多话 2021-01-16 18:12

I am beginning developing in C++ and I am developing a simple calculator in console and when my program ask to the user if wants to exit,the character \'¿\' doesn\'t appear

相关标签:
6条回答
  • 2021-01-16 18:20

    This is because the command console does not support non-ASCII characters by default (ASCII has mainly English language characters and few accented characters). To get support for characters in other character classes play around with the chcp command. Refer to it's documentation here.

    In your case I think you need to run chcp 850 in the console before running your program.

    0 讨论(0)
  • 2021-01-16 18:22

    There are a few ways to deal with this problem.

    The fundamental problem is not that the ¿ doesn't exist in the console, but that the console and your C++ text editor disagree on what that character is. The two are using different character codes for many characters beyond those needed for English. Character codes 32-126 (letters, numbers, punctuation and brackets), are universally the same. However, character codes 128 through 255, which from a Spanish point of view includes all the accented characters, "u with diaeresis" (e.g. "pingüino"), Ñ, and the starting ¿ and ¡, depend on the specific environment.

    Why have such an inconvenient disagreement in character codes is a historical accident, interesting on its own but out of the scope of this question. To keep it simple: in the Windows OS, "consoles" (typically) use the list of characters described in OEM Code Page 437, while Windows applications like your C++ editor (typically) use the Windows-1252 Code Page.

    There is no portable (universal) solution for this problem, because the issue of differing charsets is a platform-specific problem. Windows is unfortunately somewhat unique in that the editor and (console) outputs use different sets.

    The first and simplest solution - which is fine for toy programs - is to just look up the character code that you want from the OEM 437 code-page, and use that. For ¿, that's #168 (0xa8 in hex, or \250 in octal). You can just embed the character code in the string to make clear what you're trying to do, either of these:

    std::cout << ""\x0a8""Cu""\x0a0""l es el primer n""\x0a3""mero?\n"; // hex
    std::cout << "\250Cu\240l es el primer n\243mero?\n";  // octal
    

    Outputs:

    ¿Cuál es el primer número?
    

    Note how I had to do the same thing with the ú and the á. Unfortunately, writing strings like this gets unwieldy quickly. using macros or const chars can help, but not much.

    A second alternative is to use a Windows function such as CharToOemA. For example1:

    #include <windows.h>
    ...
    ...
    char pregunta[] = "¿Cuál es el primer número\n";
    char *pregunta_oem  = new char[sizeof(pregunta)/sizeof(char)];
    CharToOemA(pregunta, pregunta_oem);
    std::cout << pregunta_oem;
    delete []pregunta_oem;
    

    For a more complex program, I would wrap that pattern into a utility function or class.

    A different approach is to change the Code Page of the console, so that it agrees with your C++ editor and the rest of Windows. You can do that via the CHCP console command, or via the SetConsoleOutputCP() function, but that doesn't work on the default "raster font" used by consoles, so you have to change the font as well. When the font is set to a unicode font like Lucida Console, this works:

    std::cout << "¿Cuál es el primer número?\n"; // ┐Cußl es el...
    UINT originalCP = GetConsoleOutputCP();
    SetConsoleOutputCP(1252);
    std::cout << "¿Cuál es el primer número?\n"; // ¿Cuál es el...
    SetConsoleOutputCP(originalCP);
    

    (I don't know if you can change the font from the program itself; I have to look that up. The standard way to do it from the console is to click on the tiny icon on the corner, click Properties, Font tab, and pick a font from the list).


    1 I have to warn that this snippet contains a number of subtleties that can easily trip a beginner. You have to make sure the source of the text is a char array; if you're using a char pointer, sizeof won't work correctly and you have to use strlen(source)+1. For the source I used the natural option of a char array initialized to a literal, but you can't do that for the destination because the contents of such an array are read/only. If you are using a new'd char array or one that is not initialized to a literal, you can use the same char array for the source and destination. This example feels very C-like.

    0 讨论(0)
  • 2021-01-16 18:31

    Assuming you are using simple call to std::cout, you should be able to print Unicode strings, if you set your command line to Unicode mode:

    1. Change code page to UTF-8

    You can do this by simply calling the command below in your cmd:

    chcp 65001
    

    2. Make sure you are using a font which has the characters you want to display

    Lucidia Console should do the trick, as it supports ¿ (and other characters included in WGL4).

    0 讨论(0)
  • 2021-01-16 18:32

    this character is simply not included in basic ascii. Try using wstring http://www.cplusplus.com/reference/string/wstring/

    0 讨论(0)
  • 2021-01-16 18:37

    As you can see in Ascii table, symbol ¿ have the code 168. You can use in output stream \ffffd to print some special character.

    0 讨论(0)
  • 2021-01-16 18:38

    You can use _setmode function to do that :

    #include <iostream>
    #include <string>
    
    #if defined(WIN32) && !defined(UNIX)
    # include <io.h>    // for _setmode()
    # include <fcntl.h> // for _O_U16TEXT
    #endif // WIN32 && !UNIX
    
    int main()
    {
    #if defined(WIN32) && !defined(UNIX)
        _setmode(_fileno(stdout), _O_U16TEXT);
      //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #endif // WIN32 && !UNIX
    
        std::wstring wstr = L"'¿' and '?'";
    
        std::wcout << L"WString : " << wstr << std::endl;
        system("pause");
        return 0;
    }
    

    To write UNICODE chars (assuming LE is the standard Windows variant of UTF-16...) out with the iostream library, call _setmode() with _O_U16TEXT and then use wcout.

    But you can't use cout anymore. It throws an assert.

    Check this answer.

    0 讨论(0)
提交回复
热议问题