Невозможно напечатать символ 'à' с помощью функции printf в C

Я хотел бы понять, почему я могу напечатать символ 'à' с помощью функций fopen и fgetc, когда я читаю файл .txt, но я не могу назначить его переменной char и распечатать с помощью функции printf.

Когда я читаю файл texte.txt, вывод:

(Вот буква, которую мы часто используем во французском языке: à)

Буква 'à' правильно читается функцией fgetc и присваивается переменной char c

См. код ниже:

int main() {

FILE *fp;
  fp=fopen("texte.txt", "r");
  if (fp==NULL) {
    printf("erreur fopen");
    return 1; 
    }
char c = fgetc(fp);
    while(c != EOF) {
      printf("%c", c);
    c = fgetc(fp);
      
    }
  printf("\n");

  return 0;

  }

Но теперь, если я попытаюсь присвоить символ 'à' переменной char, я получу ошибку! См. код ниже:


int main() {

char myChar = 'à';
printf("myChar is: %c\n", myChar);

  return 0;
  }

ОШИБКА: ./main.c:26:15: ошибка: слишком большой символ для включения символьного литерала символ myChar = 'а';

Моих знаний в C очень недостаточно, и я нигде не могу найти ответ

char подходит для 1-байтового значения, например, символов таблицы ASCII. à не помещается в 1 байт, проверьте mb_char, он сделан для многобайтовых символов, и у вас есть функции для работы с ними (mb_strlen вместо strlen). Обновлено: К сожалению, это для php, проверьте wchar_t
AR7CORE 23.12.2022 20:02

Вы ищете заголовочный файл <wchar.h>.

Haris 23.12.2022 20:12

Вы используете кодировку типа UTF-8, где рассматриваемый символ занимает несколько байтов, поэтому его нельзя сохранить в одном символе.

Shawn 23.12.2022 21:03

ouzz, int fgetc(fp) возвращает 1 из 257 различных значений. Сохранение в char иногда приводит к потере информации. Сохраните в int, чтобы избежать ошибок.

chux - Reinstate Monica 23.12.2022 21:19

Проще всего использовать строку для хранения многобайтового литерала, char *myString = "à"; printf("myChar is: %s\n", myString);.

Neil 23.12.2022 21:45
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы напечатать à, вы можете использовать широкий символ (или широкую строку):

#include <wchar.h>   // wchar_t
#include <stdio.h>
#include <locale.h>  // setlocale LC_ALL
int main() {
    setlocale(LC_ALL, "");
    wchar_t a = L'à';
    printf("%lc\n", a);
}

Вкратце: символы имеют кодировку. Программа "locale" выбирает, какая кодировка используется стандартными библиотечными функциями. Широкий символ представляет собой символ, не зависящий от локали, символ, который «может» быть преобразован в/из любой локали. setlocale установите язык вашей программы на язык вашего терминала. Это нужно для того, чтобы printf знал, как преобразовать широкий символ à в кодировку вашего терминала. L перед символом или строкой делает его широким. В Linux широкие символы находятся в UTF-32.

Обработка кодировок может быть сложной. Я могу указать на: https://en.wikipedia.org/wiki/Character_encoding , https://en.wikipedia.org/wiki/ASCII , https://www.gnu.org /software/libc/manual/html_node/Extended-Char-Intro.html , https://en.cppreference.com/w/cpp/locale , https://en.wikipedia.org/wiki /Юникод .

Вы можете кодировать многобайтовую строку прямо в исходном коде и выводе. Это будет работать только в том случае, если ваш компилятор генерирует код для многобайтовой строки в той же кодировке, с которой работает ваш терминал. Если вы измените кодировку терминала или скажете компилятору использовать другую кодировку, это может привести к сбою. В Linux везде используется UTF-8, компиляторы генерируют строку UTF-8, а терминалы понимают UTF-8.

const char *str = "à";
printf("%s\n", str);

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