Programming

snprintf 및 Visual Studio 2010

procodes 2020. 8. 20. 20:37
반응형

snprintf 및 Visual Studio 2010


불행히도 프로젝트에 VS 2010을 사용하는 데 어려움을 겪고 있으며 다음 코드가 여전히 비표준 호환 컴파일러를 사용하여 빌드되지 않는다는 것을 알았습니다.

#include <stdio.h>
#include <stdlib.h>

int main (void)
{
    char buffer[512];

    snprintf(buffer, sizeof(buffer), "SomeString");

    return 0;
}

(오류로 컴파일 실패 : C3861 : 'snprintf': 식별자를 찾을 수 없음)

나는 이것이 VS 2005의 경우라는 것을 기억하고 여전히 수정되지 않은 것을보고 충격을 받았습니다.

Microsoft가 표준 C 라이브러리를 2010 년으로 이전 할 계획이 있는지 아는 사람이 있습니까?


짧은 이야기 : Microsoft는 마침내 Visual Studio 2015에서 snprintf를 구현했습니다. 이전 버전에서는 아래와 같이 시뮬레이션 할 수 있습니다.


긴 버전 :

snprintf의 예상 동작은 다음과 같습니다.

int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );

buf_size - 1버퍼 에 최대 문자를 씁니다 . 결과 문자열 buf_size은 0이 아니면 널 문자로 종료 됩니다. 경우 buf_sizeIS는 제로, 아무것도 기록되지 않고 buffer널 포인터가 될 수있다. 반환 값은 buf_size종료 null 문자를 계산하지 않고 unlimited라고 가정하여 작성되었을 문자 수입니다.

Visual Studio 2015 이전 릴리스에는 준수 구현이 없었습니다. 대신 _snprintf()(오버플로에 _snprintf_s()널 종료자를 작성하지 않는) 및 (널 종료를 강제 할 수 있지만 작성되었을 문자 수 대신 오버 플로우에 -1을 리턴 함 )과 같은 비표준 확장 이 있습니다.

VS 2005 이상에 대한 권장 대체 :

#if defined(_MSC_VER) && _MSC_VER < 1900

#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf

__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
    int count = -1;

    if (size != 0)
        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
    if (count == -1)
        count = _vscprintf(format, ap);

    return count;
}

__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
    int count;
    va_list ap;

    va_start(ap, format);
    count = c99_vsnprintf(outBuf, size, format, ap);
    va_end(ap);

    return count;
}

#endif

snprintf is not part of C89. It's standard only in C99. Microsoft has no plan supporting C99.

(But it's also standard in C++0x...!)

See other answers below for a workaround.


If you don't need the return value, you could also just define snprintf as _snprintf_s

#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)

I believe the Windows equivalent is sprintf_s


Another safe replacement of snprintf() and vsnprintf() is provided by ffmpeg. You can checkout the source here (suggested).


I tried @Valentin Milea's code but I've got access violation errors. The only thing that worked for me was Insane Coding's implementation: http://asprintf.insanecoding.org/

Specifically, I was working with VC++2008 legacy code. From Insane Coding's implementation (can be downloaded from the link above), I used three files: asprintf.c, asprintf.h and vasprintf-msvc.c. Other files were for other versions of MSVC.

[EDIT] For completeness, their contents are as follows:

asprintf.h:

#ifndef INSANE_ASPRINTF_H
#define INSANE_ASPRINTF_H

#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
extern "C"
{
#endif

#define insane_free(ptr) { free(ptr); ptr = 0; }

int vasprintf(char **strp, const char *fmt, va_list ap);
int asprintf(char **strp, const char *fmt, ...);

#ifdef __cplusplus
}
#endif

#endif

asprintf.c:

#include "asprintf.h"

int asprintf(char **strp, const char *fmt, ...)
{
  int r;
  va_list ap;
  va_start(ap, fmt);
  r = vasprintf(strp, fmt, ap);
  va_end(ap);
  return(r);
}

vasprintf-msvc.c:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "asprintf.h"

int vasprintf(char **strp, const char *fmt, va_list ap)
{
  int r = -1, size = _vscprintf(fmt, ap);

  if ((size >= 0) && (size < INT_MAX))
  {
    *strp = (char *)malloc(size+1); //+1 for null
    if (*strp)
    {
      r = vsnprintf(*strp, size+1, fmt, ap);  //+1 for null
      if ((r < 0) || (r > size))
      {
        insane_free(*strp);
        r = -1;
      }
    }
  }
  else { *strp = 0; }

  return(r);
}

Usage (part of test.c provided by Insane Coding):

#include <stdio.h>
#include <stdlib.h>
#include "asprintf.h"

int main()
{
  char *s;
  if (asprintf(&s, "Hello, %d in hex padded to 8 digits is: %08x\n", 15, 15) != -1)
  {
    puts(s);
    insane_free(s);
  }
}

참고URL : https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010

반응형