-2

I am reading the content of a file character by character:

The file has:

000001111100000

When I use this code to read

int content;// converting to char will result in proper output.
std::ifstream fin;
fin.open("zero_one");
fin>>content;
while (!fin.eof())
{
    std::cout<<content;
    fin>>content;
}
fin.close();

I get the output as: 1111100000 (the leading zeros are not present) but the trailing zeros are present.

The concern is: as I am using >> operator to read then, why don't I get the leading zeros in output whereas as I get the trailing zeros in output.

Also, If I convert the int to char for content variable then the output is same as the content of the file. Why is this so? As far as I know, the only difference between the char and int is the size in bytes of the variable.

Amit Upadhyay
  • 7,179
  • 4
  • 43
  • 57
  • 4
    `int` only stores the value of numbers. `000001111100000` and `1111100000` have the same value. You need to read the number as a string if the actual character representation is important for your use case. – François Andrieux Jul 25 '17 at 18:25
  • 2
    "As far as I know, the only difference between the char and int is the size in bytes of the variable." That's true for the types int and char, but the >> input operator is overloaded differently for those types. –  Jul 25 '17 at 18:25
  • Here is a link: https://stackoverflow.com/questions/30580903/how-can-i-preserve-leading-zeros-when-reading-a-number-and-printing-it-later – C. Lightfoot Jul 25 '17 at 18:26
  • Interpreted as an `int`eger, "01" and "1" is the same thing. – Jesper Juhl Jul 25 '17 at 18:27
  • Would you really expect "01" to read as a different integer from "1"? Sure, you'd expect them to be different *characters* but surely those different character strings encode the same integer -- the number one. – David Schwartz Jul 25 '17 at 18:27
  • 6
    A [user fluent in C++](https://stackoverflow.com/users/5411888/amit-upadhyay) would not need to post this. – chux - Reinstate Monica Jul 25 '17 at 18:29
  • @FrançoisAndrieux That identifies the same issue but doesn’t answer “why”. – Daniel H Jul 25 '17 at 18:31
  • @chux comment++; but, you are underestimating the power of the [Dunning–Kruger effect](https://en.m.wikipedia.org/wiki/Dunning–Kruger_effect). – Jesper Juhl Jul 25 '17 at 18:32
  • @FrançoisAndrieux I knew how to preserve leading zeros and that's what I mentioned too. My main concern was as I am reading the content using the loop then why does it not show me the leading zeros. And I don't found answer there also. – Amit Upadhyay Jul 25 '17 at 18:35
  • 2
    @AmitUpadhyay If you read an `int` from a file, it will read the entire number at once, not one digit at a time. – François Andrieux Jul 25 '17 at 18:36
  • @FrançoisAndrieux: Actually, `011` and `11` are not the same. The first one is an octal constant, with a value of 9. Unless the `ios_base` flag `basefield` is first set to decimal. – Ben Voigt Jul 25 '17 at 18:41
  • @BenVoigt Huh, you’re right. I assumed based on the question that it didn’t do that for stream I/O because otherwise a different value would be extracted. – Daniel H Jul 25 '17 at 18:47
  • @DanielH: I'm having some trouble finding documentation of the default value... possibly `basefield` *is* set to decimal in OP's code. – Ben Voigt Jul 25 '17 at 18:48
  • 3
    Nah, it's not implementation dependent. The Standard (all versions from C++03 through post-C++17 draft) requires the initial flags to be `skipws | dec`. Finally found it documented at `std::basic_ios::init()`, under *Postconditions*. – Ben Voigt Jul 25 '17 at 18:51
  • 3
    You have avoided the most insidious effect of `while (!fin.eof())`, but you've left yourself open to infinite loop on invalid input because you only check for end of file, which the program may never reach if it finds bad a bad value. Recommend `while (fin>>content)` as a replacement. – user4581301 Jul 25 '17 at 18:54
  • @BenVoigt Thanks; I had given up searching for the default and determined [by experiment](http://coliru.stacked-crooked.com/a/d9fd848780a0c03f) that it was at least sometimes enabled by default. – Daniel H Jul 25 '17 at 18:56

1 Answers1

3

If content is an int, it reads the data as a single integer: you get an int with the value 1111100000. If content is a char, it reads each character separately.

You can see the difference if, in the while loop, you say std::cout<<content<<'\n'; instead of just std::cout<<content;. Then if content is an int you will see one line containing 1111100000, but if it’s a char you will see 15 lines, one for each character of input.

If you put spaces between each character of the input file, they would be read as separate ints and the results would be the same, but there would still be an important difference: the values of the chars aren’t char(0) and char(1), but '0' and '1' (0x30 and 0x31, respectively), the ASCII values of the corresponding digits. The ints on the other hand would actually be 0 or 1.

Daniel H
  • 7,223
  • 2
  • 26
  • 41