将非null终止的char*转换为int

cmo*_*rse 6 c++

我正在研究一些读入数据文件的代码.该文件经常包含以ASCII编码的各种长度的数值,我需要将其转换为整数.问题是它们不是以空值终止的,这当然会导致atoi出现问题.我一直在使用的解决方案是手动将null添加到字符序列,然后转换它.

这是我一直在使用的代码; 它工作正常,但它似乎非常kludgy.

char *append_null(const char *chars, const int size)
{
    char *tmp = new char[size + 2];

    memcpy(tmp, chars, size);
    tmp[size + 1] = '\0';

    return tmp;
}

int atoi2(const char *chars, const int size)
{
    char *tmp = append_null(chars, size);

    int result = atoi(tmp);

    delete[] tmp;   

    return result;
}

int main()
{
    char *test = new char[20];
    test[0] = '1';
    test[1] = '2';
    test[2] = '3';
    test[3] = '4';

    cout << atoi2(test, 4) << endl;
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更好的方法来解决这个问题.

jth*_*ill 14

固定格式整数转换仍然在库不会执行的手动范围内:

size_t mem_tozd_rjzf(const char *buf, size_t len)        // digits only
{
        int n=0;

        while (len--)
                n = n*10 + *buf++ - '0';

        return n;
}
Run Code Online (Sandbox Code Playgroud)
long mem_told(const char *buf, size_t len)              // spaces, sign, digits
{
        long n=0, sign=1;

        while ( len && isspace(*buf) )
                --len, ++buf;

        if ( len ) switch(*buf) {
                case '-':       sign=-1;        \
                case '+':       --len, ++buf;
        }

        while ( len-- && isdigit(*buf) )
                n = n*10 + *buf++ -'0';

        return n*sign;
}
Run Code Online (Sandbox Code Playgroud)

  • @cmorse:您接受的答案必须为每个号码执行完整复制和堆分配.这个答案只适用于现有的缓冲区.这应该**快*. (3认同)
  • @cmorse对,这个答案要快得多,因此适用于关键延迟代码。 (2认同)

Ker*_* SB 10

在C++ 11中,你可以说std::stoi(std::string(chars, size)),全部来自<string>.


Mar*_*som 9

int i = atoi(std::string(chars, size).c_str());
Run Code Online (Sandbox Code Playgroud)

  • @KerrekSB,我更倾向于使用最简单的解决方案解决问题,无论它来自哪个十年.显然每种方法都有优点和缺点. (5认同)
  • 好吧,它肯定是简短而简洁的但是做了一个strlen,一个分配,一个字符串副本,一个C字符串转换(大多数实现上没有操作但可能是另一个realloc/copy),转换然后是释放.什么浪费CPU循环,而一个循环将完成工作 (3认同)