Я хотел бы понять, почему я могу напечатать символ 'à' с помощью функций 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 очень недостаточно, и я нигде не могу найти ответ
Вы ищете заголовочный файл <wchar.h>
.
Вы используете кодировку типа UTF-8, где рассматриваемый символ занимает несколько байтов, поэтому его нельзя сохранить в одном символе.
ouzz, int fgetc(fp)
возвращает 1 из 257 различных значений. Сохранение в char
иногда приводит к потере информации. Сохраните в int
, чтобы избежать ошибок.
Проще всего использовать строку для хранения многобайтового литерала, char *myString = "à"; printf("myChar is: %s\n", myString);
.
Чтобы напечатать à
, вы можете использовать широкий символ (или широкую строку):
#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);
char
подходит для 1-байтового значения, например, символов таблицы ASCII.à
не помещается в 1 байт, проверьтеmb_char
, он сделан для многобайтовых символов, и у вас есть функции для работы с ними (mb_strlen
вместоstrlen
). Обновлено: К сожалению, это для php, проверьтеwchar_t