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
'Programming' 카테고리의 다른 글
| Python으로 오디오 재생 (0) | 2020.08.20 |
|---|---|
| 저장소 변경에 대한 이메일 알림을 보내는 Git 후크 (0) | 2020.08.20 |
| Xcode 7에서 "iTunes 연결 액세스 권한이있는 계정이 없습니다"라는 오류가 계속 나타납니다. (0) | 2020.08.20 |
| 자바 스크립트에 뮤텍스가 필요합니까? (0) | 2020.08.20 |
| 원래 목적 (0) | 2020.08.20 |