Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема sscanf с буквой я  (Прочитано 5132 раз)
0 Пользователей и 1 Гость смотрят эту тему.
LemmonRus
Помогающий

ru
Offline Offline
В правильно заданном вопросе 90% ответа.


« : 22-06-2022 10:14 » 

Встретил странную проблему в коде.
При попытке распарсить строку "Имя_ТИП01" при помощи кода
Код: (C++)
void print_ID_LEN( char * ID)
{
    int num;
    char data[50];
    int len;
    char filename[255] = { 0 };
    len = strlen(ID);
    {
        int val = sscanf(ID, "%[^0-9]%02d", data, &num);
        if ( val== 2)
        {
            printf(file, "\"%s\",\n", data);
        }
        else
        {
            printf(file, "\"%s\", \n", ID);
        }
        fclose(file);
    }
}
Обнаружил что val=1,а в  data находится всего 2 распарсеных буквы "Им" .
В ходе дальнейших изысканий выяснил что sscanf с атрибутами "%s" так же вызывает обрезание строки "Имя_ТИП01" до "Им"
то есть фактически sscanf останавливает парсинг на символе 'я' (0xFF ) .Установка локалей через setlocale не помогает.
Я сначало грешил на компилятор на создав другой проект с  этой функцией она работала нормально.Что это может быть?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 22-06-2022 19:41 » 

1. А какую локаль устанавливал? Может "я" попадает под какой-нить UTF-8? Насколько я понимаю "я" = FF в Win-1251 кодировке, в Win-DOS она же xDE или xEF, так по крайней мере у меня показывается на немец. Win-11
 
2. Если вместо "я" другая буква (не "последняя", < FF) стоит, работает?

3. Совсем тупой вопрос: содержимое data смотришь в дебуггере, или в file? "я" может и %s "отрезаться". В кач. эксперимента %ls вместо %s
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
LemmonRus
Помогающий

ru
Offline Offline
В правильно заданном вопросе 90% ответа.


« Ответ #2 : 22-06-2022 21:06 » 

1. А какую локаль устанавливал? Может "я" попадает под какой-нить UTF-8? Насколько я понимаю "я" = FF в Win-1251 кодировке, в Win-DOS она же xDE или xEF, так по крайней мере у меня показывается на немец. Win-11
 
2. Если вместо "я" другая буква (не "последняя", < FF) стоит, работает?

3. Совсем тупой вопрос: содержимое data смотришь в дебуггере, или в file? "я" может и %s "отрезаться". В кач. эксперимента %ls вместо %s
1.Проверял в обоих местах . Локаль ".1251" . Даже для прикола заменил sscanf на sscanf_l с полностью прописанной локалью . Все равно режет букву я (0xFF).
2.Да работает.
Насколько я понял это ошибка Windows Kit 8.1 там с какого то перепою работа с файлами и строками заведена на один и тот же Template в котором проверяется на секундочку EOF который то же 0xFF. Теперь ищу замену sscanf .От Windows Kit 8.1 я к сожалению отказаться не могу.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 22-06-2022 21:08 » 

Очень даже может FF → EOF, если значение getchar присвоено char: EOF == -1, а FF в char — тоже -1. Замечу, что getchar возвращает int, а не char, 0xFF можно отличить от EOF.

Значение val == 0?

Стоит почитать документацию на стандартную библиотеку С своей ОС.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 23-06-2022 07:51 » 

А если конвертнуть в юникод? В юникоде "я" совсем не FF.
В смысле как workaround. Конвертнуть исходный текст в юникод, распарсить и, если необходимо, конвертнуть обратно в 1251

Теперь ищу замену sscanf

regexp?
« Последнее редактирование: 23-06-2022 07:54 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
darkelf
Молодой специалист

no
Offline Offline

« Ответ #5 : 20-07-2022 07:06 » new

А какой у Вас компилятор? у меня в msvc 6.0 и gcc 4.8.2 в Windows XP оба дают правильный результат. Ниже тестовый пример в кодировке CP1251
Код: (C)
#include <string.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
  char data[50];
  char* ID = "Имя_ТИП01";
  int num;
  int val = sscanf(ID, "%[^0-9]%02d", data, &num);

  printf("%s %d\n", data, num);

  return 0;
}
Если его скомпилировать  и выполнить в консоли с перенаправлением в файл:
Код:
D:\de\tmp\t147\a.exe >q
А затем посмотреть содержимое файла в кодировке CP1251, то там будет:
Код:
Имя_ТИП 1
« Последнее редактирование: 20-07-2022 07:09 от darkelf » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines