Старый 21.05.2010, 21:43   #1   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Объясните, как работает sscanf

Пожалуйста. И, если можно, по-понятней, а то чтение справки не помогло. Я хотел бы разобраться с парсингом строк в С++, потому что в ЕГЭ большая часть задач С4 без этого невозможна. До экзаменов http://examcountdown.narod.ru/
  Ответить с цитированием
Старый 21.05.2010, 22:38   #2   
Форумец
 
Сообщений: 113
Регистрация: 09.09.2008
Возраст: 42

lukas вне форума Не в сети
не понятно что не понятно. строка парсится по шаблону и через элипсис записывается в таргет переменные. всё тупо
  Ответить с цитированием
Старый 22.05.2010, 17:03   #3   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Что такое эллипсис? Что значат параметры "%s", "%f" и "%d"? Для чего иногда их пишут несколько подряд? Как вычленить из строки несколько переменных различных типов, записанных через пробел?
  Ответить с цитированием
Старый 22.05.2010, 17:30   #4   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, ну ты справку вообще читал? Там все написано.
http://msdn.microsoft.com/en-us/libr...8VS.71%29.aspx
И дальше по ссылкам.
  Ответить с цитированием
Старый 22.05.2010, 17:32   #5   
Кэп Улитка
 
Аватар для Yandex
 
Сообщений: 8,067
Регистрация: 04.05.2005
Возраст: 45

Yandex вне форума Не в сети
DeniSS1, по-моему в MSDN вполне наглядный пример дан
Код:
#include <stdio.h>
void main( void )
{
char  tokenstring[] = "15 12 14...";
char  s[81];
char  c;
int   i;
float fp;

/* Input various data from tokenstring: */
sscanf( tokenstring, "%s", s );
sscanf( tokenstring, "%c", &c );
sscanf( tokenstring, "%d", &i );
sscanf( tokenstring, "%f", &fp );

/* Output the data read */
printf( "String    = %s\n", s );
printf( "Character = %c\n", c );
printf( "Integer:  = %d\n", i );
printf( "Real:     = %f\n", fp );
}


Output
String    = 15
Character = 1
Integer:  = 15
Real:     = 15.000000
%s - это строка, %f - float, %d - double.
Например, sprintf ("%f - %s", 12.333, "test");
  Ответить с цитированием
Старый 22.05.2010, 17:45   #6   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от Yandex Посмотреть сообщение
Например, sprintf ("%f - %s", 12.333, "test");
он про sscanf спросил. хотя там все также почти, но есть нюансы.
  Ответить с цитированием
Старый 22.05.2010, 17:57   #7   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
А почему тогда вот это крешится?
Цитата:
#include <iostream>
using namespace std;
char* tokenstring;
double i;
int main(){
cin >> tokenstring;
sscanf(tokenstring, "%d", &i);
cout << i;
sscanf(tokenstring, "%d%", &i);
cout << i;
system("PAUSE");
return 0;
}
  Ответить с цитированием
Старый 22.05.2010, 17:59   #8   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, где вылетает и для какой строки - мы должны протелепатировать?
  Ответить с цитированием
Старый 22.05.2010, 18:07   #9   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Part!zan, если запустить программу, то после ввода строк она выдаёт ошибку и просит отправить отчёт в Майкрософт. Выложить отчёт?
  Ответить с цитированием
Старый 22.05.2010, 18:48   #10   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, а про отладчики ты что-нть слышал? В чем ты ее компилируешь? Какую строку вводишь?
  Ответить с цитированием
Старый 22.05.2010, 19:03   #11   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Dev-C++, любая строка, состоящая из двух чисел через пробел. Или одно число. Отладчик тут какой-то кривоватый. Умею пользоваться дебаггером в Студии, но привычнее писать в Dev-C++.
P.S. Убрал ввод, сделал tokenstring="12"; Теперь на выходе число 5.92879e-323
  Ответить с цитированием
Старый 22.05.2010, 19:33   #12   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, поставь себе нормальную среду. Не хочешь MSVS - скачай CodeBlocks, хоть узнаешь, что в твоем коде происходит, а не будешь гадать.
Кстати, я понял почему у тебя падает. Ты строке память не выделил ) А 5.92879e-323 получилось, потому что ты пытался в переменную double целое число записать. Вот и получил.
  Ответить с цитированием
Старый 22.05.2010, 19:41   #13   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Спасибо, вот так заработало
Цитата:
#include <iostream>
using namespace std;
char* tokenstring;
int i;
int main(){
tokenstring=new char [20];
tokenstring="12";
sscanf(tokenstring, "%d", &i);
cout << i;
system("PAUSE");
return 0;
}
Только вот с типом double всё по-прежнему, но тип int распознаёт хорошо
  Ответить с цитированием
Старый 22.05.2010, 20:06   #14   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, чтобы считывать в переменную double делай %lf. %f для float.
  Ответить с цитированием
Старый 22.05.2010, 20:17   #15   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Всем спасибо, тема закрыта =)
  Ответить с цитированием
Старый 26.05.2010, 21:35   #16   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
Откопал более продвинутый пример -
Цитата:
char *tokenstring = "page1,page2*page3";
char o[20], f[20], s[20];
sscanf(tokenstring, "%[^','],%[^'*']*%s", o, f, s);
printf("%s\n%s\n%s\n", o, f, s );
Это очень смахивает на регулярные выражения, и об этом я ничего в MDSN не нашёл. Поясните, плиз. И, если можно, - сейчас. Завтра ЕГЭ.

Последний раз редактировалось DeniSS1; 26.05.2010 в 21:57.
  Ответить с цитированием
Старый 26.05.2010, 21:43   #17   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
DeniSS1, да как можно это не найти? http://msdn.microsoft.com/en-us/libr...=VS.71%29.aspx и тыкаешь по всем ссылкам и внимательно читаешь.
  Ответить с цитированием
Старый 31.05.2010, 22:58   #18   
Banned
 
Сообщений: 96
Регистрация: 31.05.2010
Возраст: 39

SKYnet_Main boss вне форума Не в сети
DeniSS1, НАЗВАНИЕ
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf - ввод с
преобразованием формата

СИНТАКСИС
#include <stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

#include <stdarg.h>
int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);

ОПИСАНИЕ
Группа функций scanf считывает вводимую информацию в
соответствии с форматом format так, кaк описано ниже.
Этот формат может включать в себя определители
преобразования; результаты каждого преобразования, если
они производились, будут сохраняться c помощью параметров
указателя. Функция scanf считывает информацию,
прибывающую из стандартного потока ввода stdin; fscanf
считывает информацию из потока, на который указывает
stream, а sscanf считывает информацию из символьной
строки, на которую указывает str.

Функция vfscanf является аналогом vfprintf(3) и читает
информацию из потока, на который указывает stream,
используя список указателей (см. stdarg(3)). Функция
vscanf считывает список переменных аргументов из
стандартного ввода, а функция vsscanf считывает его из
строки. Эти функции являются аналогами функций vprintf и
vsprintf соответственно.

Каждый последующий указатель на аргумент должен полностью
соответствовать определителю преобразования (однако,
обратите внимание на знак отключения ("supressor"),
описанный ниже). Все определители обозначены символом %
(знаком процента). Строка format может также содержать
другие символы. Пустые символы (такие, как пробел,
табуляция или перевод строки) в строке format
соответствуют любому количеству пустых символов (даже
нулю) в строке ввода. Все остальные символы соответствуют
только сами себе. Считывание прекращается, когда вводимый
символ не соответствует форматному символу. Считывание
также прекращается, если преобразование входящих данных не
может быть произведено (см. ниже).

ПРЕОБРАЗОВАНИЯ
После символа %, обозначающего преобразование, может быть
некоторое количество символов flag из множества,
обозначенного ниже:

* - знак отключения, или "подавитель" (supressor).
Последующее преобразование работает как обычно, но
указатель уже не используется. Результат
преобразования не учитывается.

a Это знак того, что преобразование будет равно s,
необходимая область памяти для строки будет
выделена посредством malloc, а указатель на него
станет указателем на переменную char, которая не
должна быть заранее инициализирована. Этого
преобразователя нет в ANSI C.

h Обозначает, что преобразователь будет равен dioux
или n и следующий указатель является указателем на
short int (не на int).

l Обозначает, что преобразователь будет dioux или n и
следующий указатель обозначает long int (не int),
или на то, что преобразователь будет одним из efg и
следующий указатель обозначает double (не float).
Два флага l эквивалентны флагу L.

L Обозначает, что преобразователь будет либо efg (и
следующий указатель будет являться указателем на
long double), либо преобразователь будет dioux и
следующий указатель является указателем на long
long. Обратите внимание на то, что тип long long
не является типом ANSI C. Программу, использующую
его, нельзя перенести ни в какую другую
архитектуру.

q Является эквивалентом L. Этот флаг отсутствует в
ANSI C.

Дополнением к этим флагам может быть необязательная
максимальная ширина поля, выраженная целым десятичным
числом и расположенная между знаком % и преобразованием.
Если ширина не указана, по умолчанию используется
"бесконечность"; в противном случае соответствующее
количество символов считывается в процессе преобразования.
До начала преобразования большинство преобразователей
пропускают пробелы; эти пробелы не учитываются при
определении ширины поля.

Существуют следующие преобразователи:

% (определяет символ `%'. То есть `%%' в форматной
строке соответствует символу `%' на входе);

d (преобразователь знаковых десятичных целых;
указатель должен являться указателем на переменную
типа int);

D (является эквивалентом ld; оно оставлено только для
совместимости с предыдущими версиями. Примечание:
только для libc4. В libc5 и glibc %D игнорируется,
поэтому старые программы могут не работать.);

i (преобразователь знакового целого числа; следующий
указатель должен быть указателем на int. Целое
число читается в шестнадцатеричной системе
исчисления, если оно начинается с `0x' или `0X'; в
восьмеричной системе, если оно начинается с `0'; в
любом другом случае - в десятичной системе.
Используются только те символы, которые
соответствуют используемой системе.);

o (соответствует беззнаковому восьмеричному числу;
следующий указатель должен являться указателем на
unsigned int.);

u (соответствует беззнаковому десятичному числу;
следующий указатель должен являться указателем на
unsigned int.);

x (соответствует беззнаковому шестнадцатеричному
числу; следующий указатель должен являться
указателем на unsigned int.);

X (эквивалентно x);

f (соответствует числу с плавающей точкой,
необязательно со знаком; следующий указатель должен
являться указателем на float.);

e (эквивалентно f.);

g (эквивалентно f);

E (эквивалентно f);

s (соответствует последовательности "непустых"
символов; далее следует указатель на char, а массив
должен быть достаточно большим, чтобы вместить всю
входящую последовательность, включая завершающий
символ NULL. Вводимая строка останавливается либо
на пустом символе либо при достижении максимальной
ширины поля.);

c (соответствует последовательности из width символов
(по умолчанию 1); далее следует указатель на char;
для вмещения всех символов (к ним не добавляется
завершающий NULL ) должно быть достаточно места.
Обычный пропуск начальных "пустых" символов
отключен, поэтому для пропуска "пустых" символов в
начале используйте явный пробел в формате.);

[ (определяет "непустую" последовательность из
определенного набора принятых символов; далее
следует указатель на char; для вмещения всех
символов, включая завершающий NULL, должно быть
достаточно места. Обычный пропуск начальных пустых
символов отключен. Строка должна быть из символов
в конкретном наборе или не в наборе; набор
определяется символами между скобками [ и ].
Множество исключает из себя символы, если сразу
после открывающейся скобки стоит символ ^
(циркумфлекс). Чтобы включить закрывающую скобку в
набор, поставьте ее сразу после открывающей скобки
или циркумфлекса; в любой другой позиции
закрывающая скобка будет обозначать конец набора.
Символ дефиса (-) также является специальным; когда
он расположен между двумя другими символами, он
добавляет все промежуточные символы к набору.
Чтобы включить дефис в набор, поставьте его на
последнее место перед закрывающей скобкой.
Например, `[^]0-9-]' означает набор `все символы,
кроме закрывающей скобки, кроме чисел от нуля до
9-и и кроме дефиса'. Строка заканчивается либо при
появлением символа, не включенного (или если с
циркумфлексом, то включенного) в набор, либо при
достижении максимальной ширины поля.);

p (соответствует значению указателя в формате `%p'
для printf(3); далее должен следовать указатель на
void);

n (ничего не ожидается; вместо этого символы,
принятые до этого момента с ввода, сохраняются с
помощью последующего указателя на int). Это не
преобразование, хотя оно также может быть
"подавлено" при использовании флага *. В стандарте
C сказано: `Использование директивы %n не
увеличивает показания счетчика назначения,
возвращаемые при завершении работы',- но, видимо,
это большая ошибка.


ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
Эти функции возвращают число полученных элементов ввода,
количество которых может быть в действительности меньше
количества принятых элементов или даже нуля (в случае
ошибки). Ноль обозначает, что, несмотря на доступность
данных, никаких преобразований не было сделано; обычно
такое бывает из-за неправильности входящих символов,
например, алфавитных символов для преобразования `%d'.
Значение EOF возвращается в том случае, если до начала
каких-либо преобразований произошла ошибка, например,
наступает конца файла. Если происходит ошибка или
наступает конец файла после нескольких преобразований, то
число удачно завершенных преобразований возвращается.

СМ. ТАКЖЕ
strtol(3), strtoul(3), strtod(3), getc(3), printf(3)

СООТВЕТСТВИЕ СТАНДАРТАМ
Функции fscanf, scanf, и sscanf соответствуют стандарту
ANSI X3.159-1989 (``ANSI C'').

Флаг q указывается BSD 4.4 для long long, а флаги ll или L
с преобразованиями чисел указываются в GNU

Версия этих функций в Linux основана на GNU -библиотеке
libio. Более краткое описание можно найти в info
-документации GNU libc (glibc-1.08).

НАЙДЕННЫЕ ОШИБКИ
Все функции полностью совместимы с ANSI X3.159-1989, но,
кроме этого, они определяют дополнительные флаги q и a так
же, как и измененное поведение флагов L и l . Последнее
можно считать ошибкой, так как в этом случае поведение
флагов, определенное в ANSI X3.159-1989, меняется.

Некоторые комбинации флагов, определенные в ANSIC, не
имеют смысла даже для этого стандарта (например, %Ld).
Они могут иметь вполне определенное поведение в Linux, но
это не значит, что они будут вести себя так же и в других
системах. Поэтому лучше использовать флаги, не
определенные в ANSIC, т.е. использовать q вместо L в
комбинации с преобразованиями diouxX или ll.

Использование q в системе BSD 4.4 не похоже на описанное
ранее, поскольку данный флаг может быть использован при
изменяемых преобразованиях аналогично L.
как то так)
  Ответить с цитированием
Старый 31.05.2010, 23:09   #19   
Mоdеrаtоr
 
Аватар для DeniSS1
 
Сообщений: 1,617
Регистрация: 09.10.2007
Возраст: 33

DeniSS1 вне форума Не в сети
SKYnet_Main boss, большое спасибо
  Ответить с цитированием
Старый 01.06.2010, 00:06   #20   
Banned
 
Сообщений: 96
Регистрация: 31.05.2010
Возраст: 39

SKYnet_Main boss вне форума Не в сети
DeniSS1, рад помочь)
  Ответить с цитированием
Старый 22.06.2010, 22:20   #21   
Форумец
 
Сообщений: 60
Регистрация: 29.11.2009
Возраст: 37

Freedom111 вне форума Не в сети
сканировать("какой формат %d - целое %f дробное и т д", куда &переменная)
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind