Tom
Tom

Reputation: 103

why does ifstream read fail for int with 0x80000000

In a simple console application I am trying to read a file containing a hex value on each line.

It works for the first few, but after 4 or 5 it starts outputting cdcdcdcd.

Any idea why this is? Is there a limit on using read in this basic manner?

The first byte of the file is its size.

std::ifstream read("file.bin");

int* data;
try
{
    data = new int [11398];
}
    catch (int e)
{
    std::cout << "Error - dynamic array not created. Code: [" << e << "]\n"; 
}

int size = 0;
read>>std::hex>>size;
std::cout<<std::hex<<size<<std::endl;

for( int i = 0; i < size; i++)
{
    read>>std::hex>>data[i];
    std::cout<<std::hex<<data[i]<<std::endl;
}

The values I get returned are:

576 (size)    
1000323    
2000000    
1000005    
cdcdcdcd
cdcdcdcd    
cdcdcdcd    
...

The first value that is meant to be output in cdcdcdcd's place is 80000000.

Upvotes: 1

Views: 388

Answers (2)

M.M
M.M

Reputation: 141638

It sounds very much like your read fails.

Note that on a 32-bit int system, 0x80000000 is out of range for int. The range of valid values is probably -0x80000000 through to 0x7FFFFFFF.

It's important not to mix up values with representations. "0x80000000" , when read via std::hex, means the positive integer which is written as 80000000 in base 16. It's neither here nor there that a particular negative integer may be stored internally in a signed int in 2's complement with the same binary representation as a positive value of type unsigned int has when the positive integer 80000000 is stored in it.

Consider reading into unsigned int if you intend to use this technique. Also, it is essential that you check the read operation for success or failure. If a stream extraction fails then the stream is put into an error state, where all subsequent reads fail until you call .clear() on the stream.

NB. std::hex (and all other modifiers actually) are "sticky": once you set it, it stays set until you actually specify std::dec to restore the default.

Upvotes: 2

Loki Astari
Loki Astari

Reputation: 264631

You are overflowing an int.

If you change to unsigned int. You will be able to fill to 0xFFFFFFFF

You can check with:

std::cout << "Range of integer: " 
          << std::numeric_limits<int>::max() 
          << "  <Value> " 
          << std::numeric_limits<int>::min() 
          << "\n";


std::cout << "Range of integer: " 
          << std::numeric_limits<unsigned int>::max() 
          << "  <Value> " 
          << std::numeric_limits<unsigned int>::min() 
          << "\n";

Note: There is no negative hex values (it is designed as a compact representation for a bit representation).

You should really check that the read worked:

 if (read>>std::hex>>data[i])
 {
     // read worked
 }
 else
 {
     // read failed.
 }

Upvotes: 3

Related Questions