实现一个好的“itoa()"的正确方法是什么?功能? [英] What is the proper way of implementing a good "itoa()" function?

查看:12
本文介绍了实现一个好的“itoa()"的正确方法是什么?功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我对itoa"函数的实现是否正确.也许你可以帮助我让它更正确",我很确定我错过了一些东西.(也许已经有一个库按照我想要的方式进行转换,但是......找不到)

I was wondering if my implementation of an "itoa" function is correct. Maybe you can help me getting it a bit more "correct", I'm pretty sure I'm missing something. (Maybe there is already a library doing the conversion the way I want it to do, but... couldn't find any)

#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.

The only actual error is that you don't check the return value of malloc for null.

itoa 这个名字已经被用于一个非标准的功能,但并不少见.它不分配内存,而是写入调用者提供的缓冲区:

The name itoa is kind of already taken for a function that's non-standard, but not that uncommon. It doesn't allocate memory, rather it writes to a buffer provided by the caller:

char *itoa(int value, char * str, int base);

如果您不想依赖于您的平台,我仍然建议您遵循该模式.从长远来看,返回 C 中新分配的内存的字符串处理函数通常比它们的价值更麻烦,因为大多数时候您最终会进行进一步的操作,因此您必须释放大量中间结果.例如,比较:

If you don't want to rely on your platform having that, I would still advise following the pattern. String-handling functions which return newly allocated memory in C are generally more trouble than they're worth in the long run, because most of the time you end up doing further manipulation, and so you have to free lots of intermediate results. For example, compare:

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 格式说明符绝对没有不正确"的地方.

If you had reason to be especially concerned about performance (for instance if you're implementing a stdlib-style library including itoa), or if you were implementing bases that sprintf doesn't support, then you might consider not calling sprintf. But if you want a base 10 string, then your first instinct was right. There's absolutely nothing "incorrect" about the %d format specifier.

这是 itoa 的可能实现,仅适用于 base 10:

Here's a possible implementation of itoa, for base 10 only:

char *itobase10(char *buf, int value) {
    sprintf(buf, "%d", value);
    return buf;
}

这是一个结合了 snprintf 风格的缓冲区长度方法的方法:

Here's one which incorporates the snprintf-style approach to buffer lengths:

int itobase10n(char *buf, size_t sz, int value) {
    return snprintf(buf, sz, "%d", value);
}

这篇关于实现一个好的“itoa()"的正确方法是什么?功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆