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

时间:2012-01-03 17:36:50

标签: c++

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

这是我一直在使用的代码;它工作正常,但看起来非常笨拙。

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;
}

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

6 个答案:

答案 0 :(得分:13)

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

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;
}
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;
}

答案 1 :(得分:8)

int i = atoi(std::string(chars, size).c_str());

答案 2 :(得分:1)

您的方法可行,但您只需要size+1来附加null,而null将位于size位置。目前,您的测试代码实际上并没有进行函数调用,但我假设您有办法确定以null结尾的字符何时结束。如果可能的话,我建议在那里进行空终止,这样你就不必担心在你可以释放内存之前发现你遇到异常的情况(内存,老实说,如果你可能已经分配了,可能没有分配)开始捕捉异常)。

答案 3 :(得分:0)

std::string str = "1234";
boost::lexical_cast<int>(str); // 1234

答案 4 :(得分:0)

制定的问题需要在给定已知大小的数组的情况下构造一个字符串,然后将其文本转换为数值。

要将文本转换为值,C ++有一个统一的机制:流。 在您的情况下,您可以执行以下操作:

int i = 0;
std::stringstream(std::string(yourbuffer, yoursize)) >> i;

这将完全避免任何普通的旧C引用。

但是,因为 - 你说 - 所有的值都来自一个文件...为什么只是不通过std::fstream将文件本身读作一个流?

答案 5 :(得分:0)

问题是(emph mine):

  

该文件经常包含编码的各种长度的数值   在我需要转换为整数的ASCII中。问题是他们   不是以空值终止,这当然会导致atoi出现问题。

这并不会造成任何问题,因为如果我们查看atoistrtol的文档,他们会明确指出:

  

函数会丢弃任何空白字符,直到第一个非空格   人物被发现。然后它需要尽可能多的字符   形成一个有效的整数表示并将它们转换为   整数值。

这意味着,只要它们被停止转换的东西分隔,那么数字不会以空值终止并不重要。

如果它们没有分隔,那么您必须知道尺寸,当您知道尺寸时,我还会推荐像other answer中那样的手工编码解决方案。