我正在编写用作生成和输出gif图像的cgi的C程序。它们在带有表单标签的HTML页面中使用
<img src="/cgi-bin/gifprogram.cgi?param=val&etc">
,其中查询字符串参数描述了由cgi生成的图像。
_setmode(_fileno(stdout),_O_BINARY)
电话(以及一些特定于Windows的#include
)。否则你会得到通常的cr / lf问题,即每个0x0A前面都有一个假的0x0D。这在gif中并不好看:(
是否有任何可移植的解决此问题的方法,使用ANSI标准C而没有任何特定于平台的语法,并且没有很多#ifdef
内容来尝试检测Windows编译环境?此外,一些Windows编译器显然使用_setmode(_fileno(stdout),_O_BINARY)
而其他人使用setmode(fileno(stdout),O_BINARY)
,我也必须尝试检测。{/ p>
&gt;&gt;编辑&lt;&lt; 回复评论...
谢谢,伙计们。我显然必须采取其他一些完全符合posix标准/可移植的程序,并且仅仅针对Windows使用它们[nb,JoNaThAn:真的,不需要编辑以大写:), - 我的个人写作风格故意在语法上松散]。
以下是我考虑介绍的一些愚蠢行为的第一次切入。据我所知,使用mingw似乎可以工作。它是否足够,即适用于所有其他编译器?是否有必要,即使用更少/更易读的代码行完成同样的事情的任何简短/快速和肮脏的方式?
/* ---
* windows-specific header info
* ---------------------------- */
#ifndef WINDOWS /* -DWINDOWS not supplied by user */
#if defined(_WINDOWS) || defined(_WIN32) || defined(WIN32) \
|| defined(DJGPP) /* try to recognize windows compilers */ \
|| defined(_USRDLL) /* must be WINDOWS if compiling for DLL */
#define WINDOWS /* signal windows */
#endif
#endif
#ifdef WINDOWS /* Windows opens stdout in char mode, and */
#include <fcntl.h> /* precedes every 0x0A with spurious 0x0D.*/
#include <io.h> /* So emitcache() issues a Win _setmode() */
/* call to put stdout in binary mode. */
#if defined(_O_BINARY) && !defined(O_BINARY) /* only have _O_BINARY */
#define O_BINARY _O_BINARY /* make O_BINARY available, etc... */
#define setmode _setmode
#define fileno _fileno
#endif
#if defined(_O_BINARY) || defined(O_BINARY) /* setmode() now available */
#define HAVE_SETMODE /* so we'll use setmode() */
#endif
#if defined(_MSC_VER) && defined(_DEBUG) /* MS VC++ in debug mode */
/* to show source file and line numbers where memory leaks occur... */
#define _CRTDBG_MAP_ALLOC /* ...include this debug macro */
#include <crtdbg.h> /* and this debug library */
#endif
#define ISWINDOWS 1
#else
#define ISWINDOWS 0
#endif
以后确保stdout处于二进制模式的相应代码是
#if ISWINDOWS /* compiling for win... */
#ifdef HAVE_SETMODE /* try to use setmode()*/
if ( setmode ( fileno (stdout), O_BINARY) /* to set stdout */
== -1 ) /* handle error here*/ ; /* to binary mode */
#else /* setmode not available */
#if 1 /* so try this...*/
freopen ("CON", "wb", stdout); /* freopen stdout binary */
#else /* or maybe this... */
stdout = fdopen (STDOUT_FILENO, "wb"); /*fdopen stdout binary*/
#endif /* done */
#endif /* " */
#endif /* " */
您注意到我试图建议使用setmode()替代方法。虽然我的替代测试没有取得成功,但我已经将语法留待将来参考,以防其中一些最终证明是有用的。