我想知道我的“itoa”功能实现是否正确。也许您可以帮助我获得一些“正确”的信息,我敢肯定我会丢失一些东西。 (也许已经有一个图书馆按照我想要的方式进行转换,但是...找不到任何内容)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char * itoa(int i) {
char * res = malloc(8*sizeof(int));
sprintf(res, "%d", i);
return res;
}
int main(int argc, char *argv[]) {
...
最佳答案
唯一的实际错误是您没有检查malloc
的返回值是否为null。
名称itoa
已经被用于非标准的功能,但并不罕见。它不分配内存,而是写入调用方提供的缓冲区:
char *itoa(int value, char * str, int base);
如果您不想依靠您的平台拥有该功能,我仍然建议您遵循这种模式。在C中返回新分配的内存的字符串处理函数通常比长远来说要麻烦得多,这是因为大多数时候您最终都会进行进一步的处理,因此必须释放大量中间结果。例如,比较:
void delete_temp_files() {
char filename[20];
strcpy(filename, "tmp_");
char *endptr = filename + strlen(filename);
for (int i = 0; i < 10; ++i) {
itoa(endptr, i, 10); // itoa doesn't allocate memory
unlink(filename);
}
}
与
void delete_temp_files() {
char filename[20];
strcpy(filename, "tmp_");
char *endptr = filename + strlen(filename);
for (int i = 0; i < 10; ++i) {
char *number = itoa(i, 10); // itoa allocates memory
strcpy(endptr, number);
free(number);
unlink(filename);
}
}
如果您有理由特别关注性能(例如,如果您正在实现包括
itoa
的stdlib风格的库),或者正在实现sprintf
不支持的基础,那么您可以考虑不调用sprintf
。但是,如果您希望以10为底的字符串,那么您的第一个直觉是正确的。 %d
格式说明符绝对没有“不正确”。这是
itoa
的可能实现,仅适用于基础10:char *itobase10(char *buf, int value) {
sprintf(buf, "%d", value);
return buf;
}
这是一种结合了snprintf样式的缓冲区长度的方法:
int itobase10n(char *buf, size_t sz, int value) {
return snprintf(buf, sz, "%d", value);
}