在“不要这样做”的线路上,有两个非常重要的相关点值得提出:
- 不要使用
atoi
,因为它不安全。
- 不要使用
atoi
,因为它不是标准函数,而且有好的标准函数(例如snprintf
)可用于完成你想要的功能。
但是,暂且不谈这些,我想向您介绍autoconf,GNU构建系统的一部分。autoconf是一个非常全面、非常可移植的工具集,旨在使编写能够在广泛的目标系统上成功构建的代码更加容易。有人会认为,autoconf是一个过于复杂的系统,无法仅通过一个库函数解决您提出的问题,但随着任何程序的增长,它可能会面临更多类似的障碍,现在为您的程序设置autoconf将使您在未来处于更强大的位置。
从一个名为Makefile.in
的文件开始,其中包含:
CFLAGS=--ansi --pedantic -Wall -W
program: program.o
program.o: program.c
clean:
rm -f program.o program
还有一个名为configure.ac
的文件,其中包含:
AC_PREREQ([2.69])
AC_INIT(program, 1.0)
AC_CONFIG_SRCDIR([program.c])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AH_TEMPLATE([HAVE_ITOA], [Set to 1 if function atoi() is available.])
AC_CHECK_FUNC([itoa],
[AC_DEFINE([HAVE_ITOA], [1])]
)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
还有一个名为 program.c
的文件,其中包含:
#include <stdio.h>
#include "config.h"
#ifndef HAVE_ITOA
void itoa(int n, char* p) {
sprintf(p, "%d", n);
}
#endif
int main(void) {
char buffer[100];
itoa(10, buffer);
printf("Result: %s\n", buffer);
return 0;
}
现在依次运行以下命令:
autoheader
:这将生成一个名为config.h.in
的新文件,我们稍后会用到它。
autoconf
:这将生成一个名为configure
的配置脚本。
./configure
:这将运行一些测试,包括检查您是否有一个可用的C编译器,并且(因为我们要求它)是否有一个itoa
函数可用。它将其结果写入文件config.h
以供以后使用。
make
:这将编译和链接程序。
./program
:最后运行程序。
在./configure
步骤中,您将看到相当多的输出,其中包括类似以下内容:
checking for itoa... no
在这种情况下,您会看到
config.h
文件包含以下行:
/* Set to 1 if function atoi() is available. */
/* #undef HAVE_ITOA */
或者,如果您确实有atoi
可用,您将看到:
checking for itoa... yes
并且这段代码在config.h
文件中:
/* Set to 1 if function atoi() is available. */
你会发现程序现在可以读取config.h
头文件并选择定义itoa
(如果不存在的话)。
是的,这是一个解决问题的漫长过程,但你现在已经开始使用一个非常强大的工具,它可以在很多方面帮助你。
祝你好运!
autoconf
,它旨在处理此类复杂性。没有许多更简单且可靠的系统;我不确定是否知道其他的。还有与autoconf
一起使用的automake
和libtool
,但您主要是需要autoconf
。您可以调查其他构建系统,例如cmake
。 - Jonathan Lefflervoid my_itoa(int, char[]);
在具有匹配itoa()
功能/签名的系统上,让my_itoa()
调用itoa()
,可以使用inline
或#define
。在具有char * itoa(int value, char *str, int base);
的平台上(例如此处),调用itoa(value, str, 10);
。对于其他变体平台也是如此。对于缺乏任何类似itoa()
的功能的系统,请调用您自己的 代码。 - chux - Reinstate Monica#if
块中,有条件地包含您的实现:#if NEED_ITOA
int itoa(char *) { ... }
#endif
。然后在编译时,您可以为没有它的系统使用-DNEED_ITOA
。在幕后,这就是像autoconf
这样的“魔术”工具所做的所有事情(它们还帮助自动确定您需要哪些-D
标志)。但是,在C预处理器本身内部无法做到这一点。 - Sean Werkemaautoconf
功能是AC_REPLACE_FUNCS
(在页面底部,您需要阅读整个页面才能理解它的作用)。 - zwol