Thread: std::ifstream, combining formated and unformated input, possible?

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    std::ifstream, combining formated and unformated input, possible?

    A weird request perhaps, but is it possible to combine formated and unformated input when using file streams?

    What do I mean by this? Well, if you leave out the flag std::ios::binary the stream reads the characters formated, meaning if the next 3 characters are ' ', ' ' and 'A' and you read a char you don't get ' ' but 'A' since blankspace is skipped in formated input.

    I want the functionality of reading formatted integers and such, but I also want to be able to read bytes as they appear in the file at the same time (for my own customized formated input methods).

    Is this even possible?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Is this even possible?
    Not the way you want, no. Streams are either oriented as binary or text, there's no in-between and no switching orientation. The way I see it, your problem is the fact that formatted input discards whitespace that your program would otherwise use. You have a few options if you don't need the raw byte-for-byte representation of data that binary orientation gives you. Text orientation performs certain translations that you may not want. It's hard to tell, but I would wager that you can use a text oriented stream and see no ill effect.

    Your first option is to see if the noskipws modifier does what you want. It's a bit inflexible though, so your second option would be to write your own formatted input stream function or modifier that still performs the requisite conversions but doesn't ignore whitespace. The final alternative is to use character-by-character input with ch = stream.get() or stream.get(ch). Which of the latter two is easier depends on what you're trying to do exactly.
    My best code is written with the delete key.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    When you use any of the standard defined operator>>() functions, you are using formatted input. The rest of the istream functions/methods are considered unformatted input: get(), getline(), read() etc.

    ios::binary has to with newline translations when reading from a stream using unformatted input.

    Try playing around with ios::skipws format flag (which is in effect by default) and the noskipws manipulator.

    gg

    [EDIT]Beaten, stupid work - always distracting me from my posts!!![/EDIT]

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    The rest of the istream functions/methods are considered unformatted input: get(), getline(), read() etc.
    I tested this a while ago and I'm pretty sure get() is getting formated characters too, like in my example above.

    Anyway, to give a more solid example of what I'm attemting to do. I have a text file cotnaining data I'm reading into a program. One example syntax is this:
    Code:
    Object "Object 13 A"
    {
       Data1 = 0
       Data2 = 0
    }
    Most of the time parsing it is easy, you read tokens using formated inoput into std::string's or single characters. However, I want the "Object 13 A" to come as a single token. I thought if I read it unformatted byte per byte I could reqognice the first " and then keep on reading bytes until another " appears. Now, as you pointed out, this is not possble to combine with formated input.

    Trying to read formated characters will skip whitespace so the "Object 13 A" string may be defoirmed if doing that. Any clever ideas on how to solve this (apart from writing a parser from scratch)?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    get() is classified as unformatted input by the standard. It returns whitespace characters regarless of the skipws format flag.

    >>Now, as you pointed out, this is not possble to combine with formated input.
    Sure it is. You can combine all forms of input to your hearts content.

    >>I could reqognice the first " and then keep on reading bytes until another " appears.
    Of course, there's 1500 ways to parse a cat - and thats one of the methods that Prelude suggested (using get()).

    gg

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >However, I want the "Object 13 A" to come as a single token.
    This is a case where you can write your own quickie double quote parser.
    My best code is written with the delete key.

  7. #7
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Ok, it works now using get(). Thanks alot!
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

Popular pages Recent additions subscribe to a feed