sscanf - возможно ли спарсить

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Sunduk
Сообщения: 2
Зарегистрирован: 20 ноя 2017, 08:18

20 ноя 2017, 08:35

Здравствуйте. Мне необходимо функцией sscanf спарсить текст который начинаетя с 8 и содержит символы a-l o-z и цифры от 5 до 9.

Как заставить sscanf проверять первый символ на наличие 8? Сейчас в буфер попадает Hello.

Код: Выделить всё

char text[] = "Hello 8AhRE9So6PlqHab World";
char result[260];
sscanf(text, " %15[A-La-LO-Zo-z5-9]", result);
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

20 ноя 2017, 08:56

Функция scanf никогда не использовалась для валидации. По факту, она её не делает, игнорируя всё, что ей не удалось прочитать. Если нужна валидация, делай её вручную.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Sunduk
Сообщения: 2
Зарегистрирован: 20 ноя 2017, 08:18

20 ноя 2017, 09:36

Romeo писал(а):Функция scanf никогда не использовалась для валидации. По факту, она её не делает, игнорируя всё, что ей не удалось прочитать. Если нужна валидация, делай её вручную.

Тем не менее. Вопрос актуальный.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

20 ноя 2017, 10:24

Sunduk писал(а):Тем не менее. Вопрос актуальный.

Ответ - нет. Читай всю строку через fgets, затем валидируй при помощи pcre.
2B OR NOT(2B) = FF
Слива
Сообщения: 133
Зарегистрирован: 19 мар 2016, 10:15

20 ноя 2017, 15:53

Вообще-то там не Hello попадает в буфер, а просто H. А что это за каша такая в sscanf?

Код: Выделить всё

sscanf(text, " %15[A-La-LO-Zo-z5-9]", result);
Что-то я не нашел объяснение этой каше в документации. Разве так можно вообще писать?
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

20 ноя 2017, 17:18

Sunduk писал(а):Тем не менее. Вопрос актуальный.
- Хочу, чтобы кипящая вода была в твёрдом состоянии. Как это сделать?
- Это не возможно, парень.
- Тем не менее, вопрос актуальный.
Слива писал(а):А что это за каша такая в sscanf?
Ну, чисто теоретически, это не совсем каша для стандарта C99, согласно документации.
Я, правда, сам никогда не использовал форматирование [characters], но точно знаю, что принцип работы "читай, что могу, остальное игнорируй" такой синтаксис всё равно не отменяет.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
WinMain
Сообщения: 913
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

21 ноя 2017, 15:36

Лично я бы начал с того, что разделил бы исходную строку на отдельные слова и проверял бы поочерёдно каждое слово.
Но сама функция sscanf не умеет выделять отдельные слова из строки. Поэтому одной лишь функцией sscanf здесь вряд ли обойдёшься.
Аватара пользователя
Din666
Сообщения: 51
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

23 ноя 2017, 15:30

man sscanf
Знак *, помещенный после % и перед спецификатором формата, считывает данные указанного типа, но подавляет их присваивание.

sscanf(text, "%*s %1[8]%14[A-La-LO-Zo-z5-9]", &result[0], &result[1])
Слива
Сообщения: 133
Зарегистрирован: 19 мар 2016, 10:15

24 ноя 2017, 08:01

А что означает "%1[8]%14[A-La-LO-Zo-z5-9]" - можете это подробно объяснить? Объясните, пожалуйста, если сможете. :D
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

24 ноя 2017, 10:19

Din666 писал(а):man sscanf
Знак *, помещенный после % и перед спецификатором формата, считывает данные указанного типа, но подавляет их присваивание.
sscanf(text, "%*s %1[8]%14[A-La-LO-Zo-z5-9]", &result[0], &result[1])
Тем не менее, от неверных данных это всё равно не спасет.
Слива писал(а):А что означает "%1[8]%14[A-La-LO-Zo-z5-9]" - можете это подробно объяснить? Объясните, пожалуйста, если сможете. :D
Я же давал ссылку на мануал по scanf. Там подробно описан этот формат.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить