我想知道我的“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);
}

10-08 19:13