Перейти к стандартным функциям wstdio в Visual Studio 2019

Я хочу найти причину, по которой с новой функцией setlocale(LC_ALL, ".utf8") стандартная функция fgetwc() не может прочитать '\u2013' (EN DASH) из текстового файла utf8 и вместо этого возвращает WEOF. Может быть, найти обходной путь.

Я отключил «Только мой код» и включил загрузку символа для C:\WINDOWS\SysWOW64\ucrtbased.dll, который содержит fgetwc Однако, когда я пытаюсь войти в эту функцию, она не может найти fgetwc.cpp.

Эти два места не содержат этот файл, и я не могу найти другое место:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\crt\src\
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\crt\src\

Это моя тестовая программа:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <stdlib.h>

int main()
{
    wint_t wc; // = L'\u2013';
    FILE* file;
    printf("%s\n", setlocale(LC_ALL, ".utf8"));
    file = fopen("test.txt", "r");
    wc = fgetwc(file);

    // ffff '?' 0 0
    fprintf(stdout, "%04x '%lc' %d %d\n", wc, wc, ferror(file), feof(file));
    return 0;
}

Он печатает ffff вместо 2013. ferror() и feof() возвращают false.

тест.txt:

Он закодирован как E2 80 93

Попробуйте C:\Program Files (x86)\Windows Kits\10\Source\10.0.<build>\ucrt\stdio.

dxiv 12.12.2020 23:28

@dxiv это сработало. Спасибо

basin 12.12.2020 23:34

Что касается второй части, посмотрите, имеет ли значение манифест здесь.

dxiv 12.12.2020 23:37

@dxiv вы знаете, как добавить папку debug source files глобально, чтобы она была в других проектах?

basin 14.12.2020 16:58

Список каталогов исходных файлов отладки устанавливается и сохраняется для каждого решения (предположительно, в подкаталоге .vs, как указано здесь). Не знаю навскидку, откуда берутся глобальные дефолты.

dxiv 14.12.2020 18:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • Для чтения файла UTF-8 при желании отбросьте вызов setlocale и замените строку fopen на:

    file = fopen("test.txt", "r, ccs=utf-8");
    

    В документации fopen говорится:

    ccs=encoding -- Указывает набор закодированных символов для использования (один из UTF-8, UTF-16LE или UNICODE) для этого файла. Оставьте неуказанным, если вы хотите использовать кодировку ANSI.

    Похоже, это означает, что кодировка ccs=UTF-8 должна быть указана явно, чтобы прочитать файл как текст UTF-8.

    Хотя, с другой стороны, «ANSI» раньше означал либо активную кодовую страницу, либо локаль системы по умолчанию. Учитывая недавнюю поддержку UTF-8 в качестве активной кодовой страницы в Windows 10 1903 и более поздних версиях, можно было бы ожидать, что «кодировка ANSI» будет такой же, как «кодировка UTF-8», когда текущим языковым стандартом является UTF-8. Однако, похоже, это не относится к текущей реализации UCRT.

  • Для написания широкого символа #include <io.h> и <fcntl.h> замените строку fprintf на:

    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"%04x '%wc' %d %d\n", wc, wc, ferror(file), feof(file));
    

    В документации printf говорится:

    wprintf — это расширенная версия printf; формат представляет собой строку расширенных символов. wprintf и printf ведут себя одинаково, если поток открыт в режиме ANSI. printf в настоящее время не поддерживает вывод в поток UNICODE.

Другие вопросы по теме