Форум программистов, компьютерный форум CyberForum.ru

Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.95
Neonjke
18 / 18 / 1
Регистрация: 08.10.2009
Сообщений: 94
06.07.2011, 23:08     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #1
Есть следующий кусок кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
FILE* fp = fopen("G:\OPND1.txt", "r");
 
    if (fp!=NULL) // если файл удалось открыть
    {   while((ch = getc(fp)) != EOF) 
            str_file[i++]=ch; 
    
            str_file[i] = '\0';  
            cout << str_file << endl;
    }
    else printf("ERROR!");
 
    fclose(fp);
    system("Pause");
Ситуация следующая - если файл OPND1.txt (он состоит как из русских так и из латинских символов) в формате UTF-8 - то все отрабатывает как и рассчитано.
Если OPND1.txt - в формате ANSI - то текст выводится не полностью, а если быть точным, до первой буквы "я", которая на вывод не попадает, а вместо нее компилятор принимает EOF (Visual Studio 2010).

Что не так? Как исправить? Пожалуйста, помогите...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,215
Завершенные тесты: 1
06.07.2011, 23:12     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #2
Цитата Сообщение от Neonjke Посмотреть сообщение
FILE* fp = fopen("G:\OPND1.txt", "r");
fopen не найдет такого файла. нужно:
C
1
FILE* fp = fopen("G:\\OPND1.txt", "r");
и еще попробуйте читать его в бинарном режиме или используйте функцию feof().
Neonjke
18 / 18 / 1
Регистрация: 08.10.2009
Сообщений: 94
06.07.2011, 23:16  [ТС]     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #3
Цитата Сообщение от schdub Посмотреть сообщение
fopen не найдет такого файла. нужно:
C
1
FILE* fp = fopen("G:\\OPND1.txt", "r");
и еще попробуйте читать его в бинарном режиме или используйте функцию feof().

fopen прекрасно находит этот файл как и в моем, так и в Вашем варианте (возможно, это особенности среды Visual Studio).
бинарный попробую, но все таки мне интересна причина это проблемы, почему "я" интерпретируется как EOF.
Замечу, что когда файл в UTF-8 или в Unicode такой проблемы не наблюдается.

Кто ответит, пожалуйста?
zuq
 Аватар для zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
06.07.2011, 23:17     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #4
Используй функцию feof(). Например цикл while(!feof(fp)) будет итерироваться до конца файла
Neonjke
18 / 18 / 1
Регистрация: 08.10.2009
Сообщений: 94
06.07.2011, 23:27  [ТС]     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #5
Не особо представляю, как должен выглядеть мой код с feof()
Куда там вставить счетчик?

Не могли бы пожалуйста переделать мой код с feof? Чтобы выполнялось то же самое.
zuq
 Аватар для zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
06.07.2011, 23:29     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    FILE* fp = fopen("G:\OPND1.txt", "r");
 
        if (fp!=NULL) // если файл удалось открыть
        {       while(!feof(fp)) {
                        ch = getc(fp)
                        str_file[i++]=ch;
 
                        str_file[i] = '\0';
                        cout << str_file << endl;
        }
        else printf("ERROR!");
 
        fclose(fp);
        system("Pause");
Как-то так
Neonjke
18 / 18 / 1
Регистрация: 08.10.2009
Сообщений: 94
06.07.2011, 23:31  [ТС]     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #7
Благодарю.
В действительности вопрос от моей лени, поправил как у вас, но забыл запихнуть в цикл строчку
ch = getc(fp)

И дивился ошибкам. =)
zuq
 Аватар для zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
06.07.2011, 23:32     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #8
Бывает
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,215
Завершенные тесты: 1
06.07.2011, 23:34     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #9
zuq, строка 7 пропущен }
zuq
 Аватар для zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
06.07.2011, 23:36     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #10
schdub, Да пропущен. Как-то не обратил внимания. Я в исходный код от автора просто feof() подставил, за другим уже не следил
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
07.07.2011, 00:45     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #11
Сдаётся мне, что в самой первой программе ch объявлен как char, потому как если бы он был объявлен как int, то и с первым кодом проблемы бы не было.
Bers
Заблокирован
07.07.2011, 01:00     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #12
Цитата Сообщение от grizlik78 Посмотреть сообщение
Сдаётся мне, что в самой первой программе ch объявлен как char, потому как если бы он был объявлен как int, то и с первым кодом проблемы бы не было.
странно... ANSI же 1 байтовый. Не нужен для него никакой int
Может ТС ANSI с юникодом попутал?
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
07.07.2011, 01:07     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #13
Bers, ничего ни я, ни ТС не путали. Функция (f)getc() возвращает именно int. Угадай, почему? Потому, что иначе нет никакой возможности отличить признак конца файла (EOF == -1) от символа с кодом 255 (что для знакового char тоже -1).
Bers
Заблокирован
07.07.2011, 01:22     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #14
Цитата Сообщение от grizlik78 Посмотреть сообщение
Bers, ничего я не путал. (f)getc() возвращает именно int. Угадай, почему? Потому, что иначе нет никакой возможности отличить признак конца файла (EOF == -1) от символа с кодом 255 (что для знакового char тоже -1).
Ну во-первых, я не говорил, что вы что-то попутали. Вы же не ТС.

А во вторых, getc() действительно возвращает int, но она полностью совместима с ANSI Си.
Это значит, что ... приведение int к unsigned char должно быть без потерь данных.

Если конечно ТС юзал знаковый чар.... моя студия на такие косяки обычно сыплет предупреждениями... ошибки из-за потерь данных... наверное, случаются только у тех, кому не интересно программировать, и читать что-то там пишит компилятор. Типа работает, и ладна.

Добавлено через 2 минуты
не не, я что-то похоже сам туплю.

беззнаковый чар тут тоже не вопрёццо. Нет, нужно юзать int без всяких приведений. И не париццо.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
07.07.2011, 01:31     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #15
Во-первых, char по-умолчанию почти везде знаковый. Мало где можно встретить беззнаковый char по-умолчанию.
Во-вторых, если бы можно было бы сохранить всю информацию в char, то getc() и возвращала бы char. И знаковость здесь роли не играет.
В коде:
C
1
2
char ch;
while ((ch = getc(fp)) != EOF)
потеря информации происходит как раз при присвоении значения переменной ch, так как для "законных" символов эта функция возвращает числа 0—255, а в случае конца файла, функция возвращает EOF, то есть -1. После присваивания нельзя отличить EOF от символа с кодом 255.
А вот здесь можно:
C
1
2
int ch;
while ((ch = getc(fp)) != EOF)
Добавлено через 2 минуты
Что-то я долго пишу и тоже не сразу понимаю некоторые фразы
Bers
Заблокирован
07.07.2011, 01:39     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #16
Цитата Сообщение от grizlik78 Посмотреть сообщение
Что-то я долго пишу и тоже не сразу понимаю некоторые фразы
время без 20 минут 2 часа ночи. Как бы... ничего страшного)
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
07.07.2011, 09:46     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #17
Цитата Сообщение от zuq
Используй функцию feof(). Например цикл while(!feof(fp)) будет итерироваться до конца файла
это неправильно
если будет ошибка чтения файла, конец файла никогда не наступит

Цитата Сообщение от grizlik78
Во-первых, char по-умолчанию почти везде знаковый. Мало где можно встретить беззнаковый char по-умолчанию.
надо расчитывать, что он знаковый или беззнаковый
так же, как int - это short или long

Цитата Сообщение от Bers
странно... ANSI же 1 байтовый. Не нужен для него никакой int
EOF - это число, которое меньше нуля
C89
4.9 INPUT/OUTPUT <stdio.h>

...

EOF

which expands to a negative integral constant expression that is
returned by several functions to indicate end-of-file ,that is, no
more input from a stream;
коды символов лежат в диапазоне от 0 до 255
-1 - 11111111
255 - 11111111

даже если char равен unsigned char, то:
-1 - 11111111
255 - 11111111

поэтому делается int, в котором:
-1 - 11111111111111111111111111111111
255 - 00000000000000000000000011111111

Цитата Сообщение от Neonjke
fopen прекрасно находит этот файл как и в моем, так и в Вашем варианте
бекслеш используется для экранирования, следовательно, будет попытка обработать экранирующую последовательность \O, которой не существует
никаких манипуляций с неявным преобразованием \O в \\O не должно быть

C
1
2
3
4
5
6
7
#include <stdio.h>
 
int main(void)
{
    printf("\O");
    return 0;
}
Код
[guest@localhost tests]$ .ansi t.c -o t
t.c: В функции ‘main’:
t.c:6:12: предупреждение: unknown escape sequence: '\O'
[guest@localhost tests]$
C89
A.6.2 Undefined behavior

...

* An unspecified escape sequence is encountered in a character
constant or a string literal ($3.1.3.4).
Добавлено через 17 минут
в C99 пишут, что маленький буквы зарезервированы для будущих стандартов языка
а другие символы, отличные от стандартных и зарезервированных, могут использоваться в расширениях

то есть из этого следует, что даже если компилятор использовал бы С99, то он не имел бы права использовать в fopen пути вида c:\abc
если у тебя прокатывает один бекслеш (не слеш, слеши там можно применять), то он либо запрещает имена файлов маленькими буквами, либо нарушает стандарт языка

Visual Studio 2010 использует C89, в котором любая нестандартная экранирующая последовательность - undefined behavior
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
07.07.2011, 11:05     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #18
Цитата Сообщение от accept Посмотреть сообщение
надо расчитывать, что он знаковый или беззнаковый
так же, как int - это short или long
Если честно, то мысль не понял.
short int, int, long int могут отличаться размером, могут не отличаться, но все они гарантированно знаковые.
char, unsigned char, signed char имеют одинаковый размер, но если про второй и третий можно сказать, что они беззнаковый и со знаком соответственно, то про char такого сказать нельзя. Он может оказаться как беззнаковым, так и со знаком. Это 3 разных типа, хотя реализация char должна совпадать либо с unsigned char либо с signed char
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
08.07.2011, 01:50     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #19
Цитата Сообщение от grizlik78
Если честно, то мысль не понял.
нельзя полагаться на то, что char имеет знак
так же, как нельзя полагаться на то, что int больше 32767

Цитата Сообщение от grizlik78
Во-первых, char по-умолчанию почти везде знаковый. Мало где можно встретить беззнаковый char по-умолчанию.
ключевое слово signed придумали из-за этой особенности char
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2011, 02:02     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF)
Еще ссылки по теме:

Работа с файлами (вывести в текстовый файл "g.txt" любую цифру из исходного файла "f.txt" с сохранением строгого порядка) C++
Char *(UTF-8) -> char *(ANSI) C++
C++ Проверить, встрачается ли в заданном тексте буква "а" чаще, чем буква "b"

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
08.07.2011, 02:02     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) #20
Цитата Сообщение от accept Посмотреть сообщение
нельзя полагаться на то, что char имеет знак

Не по теме:

Надеюсь никто не обвиняет меня в том, что я на это полагаюсь. Потому как я как раз и говорю, что он может быть любым.
Никому нельзя верить (c)

Yandex
Объявления
08.07.2011, 02:02     Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF)
Ответ Создать тему
Опции темы

Текущее время: 04:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru