ПрограммированиеФорумОбщее

sscanf & sscanf_s

Страницы: 1 2 Следующая »
#0
0:49, 28 фев 2008

Объясните плиз, в чём разница?

работает:

...
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

#1
0:55, 28 фев 2008

если я не ошибаюсь надо вот так.

sscanf_s( string, "%s", parameter, sizeof(parameter) ); 
#2
1:11, 28 фев 2008

Читаем дружно 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 );
}
#3
1:51, 28 фев 2008

Теперь виснет на fclose :(

#4
2:00, 28 фев 2008

Dronas
покажи код.

Прошло более 3 лет
#5
21:11, 13 июня 2011

Возникла проблема с функцией sscanf. Мне нужно сделать над ней обёртку, но я не знаю как. Я знаю, что когда делают обёртку над sprintf, её заменяют на аналогичную функцию, принимающую va_list, но у sscanf такого аналога нет. Точнее, я видел vscan_fn, который принимает va_list в исходном файле sscanf.c, но не могу его импортировать. Наверное, это из-за того, что он объявлен как static.
P. S. извините за некропостинг.

#6
10:56, 14 июня 2011

Оответьте, пожалуйста. Мне нужно передать аргументы из моей функции, принимающей переменное число аргументов в ssanf. Как можно это сделать?

#7
12:05, 14 июня 2011

gammaker
> Оответьте, пожалуйста. Мне нужно передать аргументы из моей функции,
> принимающей переменное число аргументов в ssanf. Как можно это сделать?
Ну нет под виндой vsscanf(), нет и все тут. Переходи на линукс или спиши с гугла что-нибудь брутальное типа этого или этого.

#8
12:21, 14 июня 2011

Никак. Нельзя оттранслировать неопределенное число аргументов в функцию ниже.

#9
16:15, 14 июня 2011

>Переходи на линукс
Из-за какого-то vsscanf переходить на Линукс и терять 99% (возможных) пользователей?! Не вариант...
>спиши с гугла что-нибудь брутальное типа этого или этого
Посмотрел. Первая ссылка подходит лучше - там не используется ассемблер, который непереносим на разные платформы.
Может, есть способ импортировать встроенную функцию vscan_fn? Я изучал работу sscanf, оказалось, что она вызывает vscan_fn, который принимает va_list, но он объявлен как static.

#10
16:43, 14 июня 2011

Ну если тебе плевать чья реализация, то просто скачай сорцы рантайма GCC и возьми оттуда vsscanf()

#11
16:57, 14 июня 2011

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);
}
#12
18:07, 14 июня 2011

>Ну если тебе плевать чья реализация, то просто скачай сорцы рантайма 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 просто обнуляет переданную ему переменную и всё.

#13
18:47, 14 июня 2011

А если просто скопировать функцию vscan_fn к себе в сорцы?

#14
18:57, 14 июня 2011

>А если просто скопировать функцию vscan_fn к себе в сорцы?
Вряд ли получится. Там столько зависимостей.
Решил использовать временно вариант, о котором написал выше. Потом попробую сделать как-нибудь без sscanf при помощи шаблонов. Правда, тогда придётся одну функцию продублировать много раз. И почему в C++ не сделали нормальную поддержку переменного числа параметров функций?

Страницы: 1 2 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.