wscanf () ведет себя иначе, чем scanf () при получении ввода - PullRequest
1 голос
/ 20 октября 2019

У меня есть простая программа, которая принимает пользовательский ввод в виде строки и выводит введенную строку. Единственное отличие состоит в том, что я предоставил пользователю два варианта:

Первый для ввода базовой строки .

Второй для ввода строки шириной .

scanf () успешно принимает пользовательский ввод для базовой строки, но wscanf () не запрашиваетдля ввода пользователя и просто выйти.

Почему это происходит с wscanf (), а не с scanf ()? Как бы взять пользовательскую строку ввода из wscanf () в той же программе.

#include <stddef.h>
#include <stdio.h>
#include <wchar.h>

void basic()
{
    char str[100];
    printf("Enter string with basic string char: ");
    scanf("%s", str);
    printf("Entered string : %s \n", str);
}

void wide()
{
    wchar_t str[100];
    wprintf(L"Enter string with wide string char: ");
    wscanf(L"%ls", str);
    wprintf(L"Entered string : %ls \n", str);
}


int main(int argc, char **argv)
{
    int option = 1;
    printf("\n Basic string (char*) vs Wide string (wchar_t*) \n\n");
    printf("1. Basic string \n2. Wide string \n");
    printf("Enter choice : ");
    scanf("%d", &option);
    switch(option)
    {
    case 1:
        basic();
        break;
    case 2 :
        wide();
        break;
    default:
        printf("Invalid choice \n");
    }

    return 0;
} 

Выход:

1. Базовая строка:

Basic string (char*) vs Wide string (wchar_t*) 

1. Basic string 

2. Wide string 

Enter choice : 1

Enter string with basic string char: hello

Entered string : hello 

2. Широкая строка:

Basic string (char*) vs Wide string (wchar_t*) 

1. Basic string 

2. Wide string 

Enter choice : 2

Ответы [ 2 ]

1 голос
/ 21 октября 2019

wscanf () ведет себя иначе, чем scanf () при получении ввода

Ориентация.

Первое использование кода stdin - scanf("%d", &option) создание байтово-ориентированного потока .

После использования wscanf(L"%ls", str); - UB. Придерживайтесь одной ориентации или повторно открывайте файлы.

Каждый поток имеет ориентацию. После того, как поток связан с внешним файлом, но перед выполнением каких-либо операций с ним, поток не имеет ориентации. Как только функция ввода / вывода широких символов была применена к потоку без ориентации, поток становится широко ориентированным потоком. Точно так же, как только байтовая функция ввода / вывода была применена к потоку без ориентации, поток становится потоком с байтовой ориентацией. В противном случае только вызов функции freopen или функции fwide может изменить ориентацию потока. (Успешный вызов freopen удаляет любую ориентацию.) C11 §7.21.2 4.

Аналогичная проблема относится к stdout.

0 голосов
/ 20 октября 2019

Первая команда scanf() scanf("%d", &option); оставляет \n в stdin, которую wscanf() ловит. Это то, что вызывает ошибку, я думаю. У меня была похожая проблема неделю назад. Вы можете прочитать больше об этом здесь , где вы можете найти хорошие ответы и обходные пути, которые у меня есть.

Вы можете либо поставить getchar() после scanf(), чтобы вытащить \n или избегайте использования scanf() в целом и используйте альтернативу, например sscanf().

...