Объясните плиз, в чём разница?
работает:
... char string[MAX_PATH]; char parameter[MAX_PATH]; ... fgets(string, MAX_PATH, file); sscanf(string, "%s", parameter); ...
не работает (Access violation):
... char string[MAX_PATH]; char parameter[MAX_PATH]; ... fgets(string, MAX_PATH, file); sscanf_s(string, "%s", parameter); ...
OS - Vista
если я не ошибаюсь надо вот так.
sscanf_s(string, "%s", parameter, sizeof( parameter) );
Читаем дружно MSDN.
The sscanf_s function reads data from buffer into the location given by each argument. The arguments after the format string specify pointers to variables with a type that corresponds to a type specifier in format. Unlike the less secure version sscanf, a buffer size parameter countOfBuffer is required when using the type field characters c, C, s, S and [. This parameter must be supplied as an additional parameter after each buffer which requires it. For more information, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l and scanf Type Field Characters.
#include <stdio.h> #include <stdlib.h> int main(void ) { char tokenstring[] = "15 12 14..."; char s[81]; char c; // Input various data from tokenstring: // max 80 character string plus NULL terminator sscanf_s( tokenstring, "%s", s, _countof( s) ); sscanf_s( tokenstring, "%c", &c, sizeof( char) ); // Output the data read printf_s( "String = %s\n", s ); printf_s( "Character = %c\n", c ); }
Теперь виснет на fclose :(
Dronas
покажи код.
Возникла проблема с функцией sscanf. Мне нужно сделать над ней обёртку, но я не знаю как. Я знаю, что когда делают обёртку над sprintf, её заменяют на аналогичную функцию, принимающую va_list, но у sscanf такого аналога нет. Точнее, я видел vscan_fn, который принимает va_list в исходном файле sscanf.c, но не могу его импортировать. Наверное, это из-за того, что он объявлен как static.
P. S. извините за некропостинг.
Оответьте, пожалуйста. Мне нужно передать аргументы из моей функции, принимающей переменное число аргументов в ssanf. Как можно это сделать?
gammaker
> Оответьте, пожалуйста. Мне нужно передать аргументы из моей функции,
> принимающей переменное число аргументов в ssanf. Как можно это сделать?
Ну нет под виндой vsscanf(), нет и все тут. Переходи на линукс или спиши с гугла что-нибудь брутальное типа этого или этого.
Никак. Нельзя оттранслировать неопределенное число аргументов в функцию ниже.
>Переходи на линукс
Из-за какого-то vsscanf переходить на Линукс и терять 99% (возможных) пользователей?! Не вариант...
>спиши с гугла что-нибудь брутальное типа этого или этого
Посмотрел. Первая ссылка подходит лучше - там не используется ассемблер, который непереносим на разные платформы.
Может, есть способ импортировать встроенную функцию vscan_fn? Я изучал работу sscanf, оказалось, что она вызывает vscan_fn, который принимает va_list, но он объявлен как static.
Ну если тебе плевать чья реализация, то просто скачай сорцы рантайма GCC и возьми оттуда vsscanf()
gammaker
> Может, есть способ импортировать встроенную функцию vscan_fn?
Собери CRT из исходников, добавив нужную функциональность:
int __cdecl vsscanf (REG2 const char *string, const char *format, va_list arglist ) { FILE str; REG1 FILE *infile = &str; REG2 int retval; _ASSERTE( string != NULL); _ASSERTE( format != NULL); infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF; infile->_ptr = infile->_base = ( char *) string; infile->_cnt = strlen( string); retval = ( _input( infile,format,arglist)); return( retval); }
>Ну если тебе плевать чья реализация, то просто скачай сорцы рантайма GCC и возьми оттуда vsscanf()
Не плевать. Я специально использую старую CRT, которая есть во всех Windows'ах(по крайней мере начиная с XP), чтобы не таскать с собой dll и не линковать CRT статически. Выбрал способ по первой ссылке entryway'я. Вроде всё работает.
void String::Scan(const char* format, ...) { va_list args; va_start( args, format); void *a[16]; for( int i=0; i<16; i++) a[i]=va_arg( args, void*); sscanf( Data, format, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); }
Кстати, зачем нужен va_end? В книге Страуструпа написано, что эти макросы производят какие-то манипуляции со стеком, а va_end возвращает стек в нормальное состояние, но оказалось, что va_end просто обнуляет переданную ему переменную и всё.
А если просто скопировать функцию vscan_fn к себе в сорцы?
>А если просто скопировать функцию vscan_fn к себе в сорцы?
Вряд ли получится. Там столько зависимостей.
Решил использовать временно вариант, о котором написал выше. Потом попробую сделать как-нибудь без sscanf при помощи шаблонов. Правда, тогда придётся одну функцию продублировать много раз. И почему в C++ не сделали нормальную поддержку переменного числа параметров функций?
Тема в архиве.