Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert non-null-terminated char* to int

Tags:

c++

I am working on some code that reads in a data file. The file frequently contains numeric values of various lengths encoded in ASCII that I need to convert to integers. The problem is that they are not null-terminated, which of course causes problems with atoi. The solution I have been using is to manually append a null to the character sequence, and then convert it.

This is the code that I have been using; it works fine, but it seems very 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;
}

I am wondering if there is a better way to approach this problem.

like image 462
cmorse Avatar asked Jan 03 '12 17:01

cmorse


People also ask

Are all char * null terminated?

char arrays are not automatically NULL terminated, only string literals, e.g. char *myArr = "string literal"; , and some string char pointers returned from stdlib string methods.

What happens if string is not null terminated?

Many library functions accept a string or wide string argument with the constraint that the string they receive is properly null-terminated. Passing a character sequence or wide character sequence that is not null-terminated to such a function can result in accessing memory that is outside the bounds of the object.

What does itoa mean c++?

The itoa() function coverts the integer n into a character string. The string is placed in the buffer passed, which must be large enough to hold the output. The radix values can be OCTAL, DECIMAL, or HEX.


2 Answers

Fixed-format integer conversion is still well within handroll range where the library won't do:

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;
}
like image 144
jthill Avatar answered Oct 06 '22 03:10

jthill


In C++11, you can say std::stoi(std::string(chars, size)), all from <string>.

like image 28
Kerrek SB Avatar answered Oct 06 '22 03:10

Kerrek SB