Hi,

I am using the following code to convert character array in file to integer.
However, the problem is that there is only one place in the file where it does not convert the character array to integer correctly.

Since my code is big, i am pasting the most relevant part.

if(c == 'n')
            {
                if((c=getc(fp)) == 'e')
                {
                    if((c=getc(fp)) == 't')
                    {
                        c=getc(fp);            // For the '_' after net.
                        arr1 = new char[3];
                        int i = -1;
                        while(1)
                        {
                            c=getc(fp);                // Get the number.
                            cout << "c = " << c << " ; ";
                            if(c == ';' || c == ' ' || c == ',' || c == ')' || c == '=' || c == '<')
                            {
                                cout << "c2 = " << c << " ; ";
                                break;
                            }
                            else
                            {
                                i = i + 1;
                                cout << "c1 = " << c << " ; ";
                                arr1[i] = c;
                            }
                        }
                        numo = atoi(arr1);
                        //sscanf (arr,"%d",&numo);
                        delete arr1;
                        keep.insert(numo);
                        cout << " NET num =  " << numo << endl;
                    }
                }
            }

in the file :

not( net_2584, net_2546);
    not( net_2585, net_2499);
    not( net_2586, net_2490);
    not( net_2587, net_2474);
    not( net_2588, net_2502);
    not( net_2589, net_2505);
    not( net_2590, net_2507);

It reads 2490 as 24900.

I do not understand why.
Is there a better way to convert a character array to integer when the size of character array is not known before hand.

Any help is appreciated. Thanks.

Dani AI

Generated

The observed result (net_2490 turning into 24900) is a textbook case of undefined behavior from a non-terminated, too-small C-string plus an out-of-bounds write. As noted, the buffer in the posted code is undersized and never gets a terminating '\0', so atoi walks past the intended digits and consumes whatever garbage happens to be next in memory (which can look like an extra '0'). Also note two additional hazards in the posted approach: getc() returns an int and should be checked for EOF, and arrays allocated with new[] must be freed with delete[] (using delete on new[] is undefined).

A safer, clearer approach is to stop managing raw char arrays and use std::string to collect digit characters, then convert using a robust parser. std::from_chars (C++17) is non-throwing and fast; std::stoi or strtol are acceptable fallbacks if from_chars is not available. Example pattern:

#include <string>
#include <charconv>
#include <cctype>

std::string token;
int ch;
while ((ch = getc(fp)) != EOF) {
    if (std::isdigit(static_cast<unsigned char>(ch))) {
        token.push_back(char(ch));
    } else if (!token.empty()) {
        int value = 0;
        auto res = std::from_chars(token.data(), token.data() + token.size(), value);
        if (res.ec == std::errc()) keep.insert(value);
        token.clear();
    }
}

Quick checklist and troubleshooting notes:

  • Always reserve room for the terminating NUL if using C-strings; prefer std::string to avoid manual termination.
  • Check bounds before writing; avoid out-of-range array access.
  • Use delete[] for new[] allocations.
  • Treat getc() as returning int and test for EOF.
  • Prefer std::from_chars (no exceptions) or strtol for C-style fallback; handle conversion errors explicitly.
  • If C-style scanning is required, fscanf can work, but parsing into a std::string then converting is clearer and less error-prone (as suggested, but modern C++ gives safer alternatives).

Recommended Answers

All 2 Replies

I think the array: arr1 = new char[3];
is too small. why isn't it arr1 = new char[5]? I would set arr1[4]='\0' to ensure it gets interpreted as a c-string.

why are you doing that the hard way, such as one character at a time, when there are much faster, easier, and less error-prone ways, such as fscanf() . If your instructor requires you to do it that way, then do it. Otherwise you have just wasted how many hours??

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.