sprintf против всех...
От: Аноним  
Дата: 06.09.04 08:41
Оценка: -2
"Как отформатировать выводимую строку?" — каждый из нас, я уверен, задавался таким вопросом. Не секрет, что сейчас к старому доброму sprintf'у добавилось множество современных выводов на экран: iostream, stringstream, boost. Про их сравнение хорошо рассказывает известная статья. Printf хорош своими скоростью, простотой и наглядностью, но небезопасен: нет ни проверки типов аргументов, ни размера буфера. Правда, первая проблема уже решена современными компиляторами или утилитами типа Lint. Проблема размера буфера решается в ф-ции _snprintf, но даже она не может предотвратить, скажем, передачу некорректных указателей. Но решение есть! Это — исключения, штатный механизм C++. Просто взгляите на этот код:

void safeSprintf(char *Dst, int DstSize, char *Format, ...)
{
   va_list marker;
   va_start(marker, Format);
   try
   {
      _vsnprintf(Dst, DstSize, Format, marker); // Главное действо
   }
   catch(...)
   {
      WriteLog("criticals.log", "PARSER Exception in safeSprintf!");

      try // сбойную строку с форматированием - в лог
      {
         char TmpBuf[STDSIZE];

         strncpy(TmpBuf, Format, STDSIZE);
         TmpBuf[STDSIZE-1] = 0; // т.к. strncpy не добавляет NULL при переполнении
         prsReplaceChar(TmpBuf, '%', '_'); // убираем форматирование
         WriteLog("criticals.log", TmpBuf);

         strcpy(Dst, "ERROR! PARSER Exception in safeSprintf!");
      }
      catch(...)
      {
         WriteLog("criticals.log", "PARSER Exception while processing exception!");
      }
   }// catch
   va_end(marker);
}


Механизм исключений убирает главную проблему sprintf — недостаток надежности. Такая редакция ф-ции держит даже конструкции типа
safeSprintf(NULL, 1024*1024, NULL, NULL);

— без выпадений, но с записью сбойных операторов в лог для ошибок!

Станет ли такой safeSprintf новой жизнью для sprintf?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.