File Processing

Discussion in 'C++' started by Kapil Khosla, Aug 19, 2003.

  1. Kapil Khosla

    Kapil Khosla Guest

    Hi,
    I have a file with the format
    //////////
    {blkid:= 10000}
    dfd dfd
    dfdfdfd
    dfd dfd
    {blkid:= 10001}
    dfd fddd
    gdfd dd
    dfdd
    ere
    ///////

    I want to set '{' as a delimiter and read everything between into a
    std::string.
    I checked out getline but it expects a "size", in my case I dont know
    how big
    will the buffer be so how should I solve this problem. I have attached
    a sample code which compiles but does not give me the string I expect.
    Can you help.
    Thanks.
    Kapil
    // semantics_of_data.cpp : Defines the entry point for the console
    application.
    //

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <string>

    using namespace std;

    int _tmain(int argc, _TCHAR* argv[])
    {
    ifstream sample("sample.dat",ios::in);
    ifstream outfile("temp.dat",ios::eek:ut);
    char buf[10];
    std::string sample_buf;

    if(!sample || !outfile)
    {
    exit(0);
    }

    while(!sample.eof())
    {
    sample.getline(const_cast<char*>(temp_buf.c_str()),30,'{');
    outfile << temp_buf;

    }

    gets(buf);

    return 0;
    }
    Kapil Khosla, Aug 19, 2003
    #1
    1. Advertising

  2. Kapil Khosla

    Mike Wahler Guest

    Kapil Khosla <> wrote in message
    news:...
    > Hi,
    > I have a file with the format
    > //////////
    > {blkid:= 10000}
    > dfd dfd
    > dfdfdfd
    > dfd dfd
    > {blkid:= 10001}
    > dfd fddd
    > gdfd dd
    > dfdd
    > ere
    > ///////
    >
    > I want to set '{' as a delimiter and read everything between into a
    > std::string.
    > I checked out getline but it expects a "size", in my case I dont know
    > how big
    > will the buffer be so how should I solve this problem.


    Don't use the member function 'getline()', use the
    'free' function 'getline()' declared by <string>.
    This function allows the specification of a delimiter,
    and also stores the input directly into a 'std::string'
    object, no messing about with arrays.

    > I have attached
    > a sample code which compiles


    I see at least a few things that I think should prevent it
    from compiling. See below.

    >but does not give me the string I expect.
    > Can you help.
    > Thanks.
    > Kapil
    > // semantics_of_data.cpp : Defines the entry point for the console
    > application.
    > //
    >
    > #include "stdafx.h"


    This is a nonstandard, Microsoft-specific header.
    Please omit such from code posted here. It's
    certainly not necessary for what you're asking about.

    > #include <iostream>
    > #include <fstream>
    > #include <string>
    >
    > using namespace std;
    >
    > int _tmain(int argc, _TCHAR* argv[])


    Eh? More 'Microsoft-isms?'. The language discussed
    here is ISO standard C++, for which the *only* allowed
    name for the entry-point function is 'main()'.

    Also _TCHAR is some platform-specific type, not allowed
    by the language definition (unless it resolves to the
    C++ type 'char').

    Why declare these parameters at all anyway? You're
    not using them.

    > {
    > ifstream sample("sample.dat",ios::in);
    > ifstream outfile("temp.dat",ios::eek:ut);


    Note that it's redundant to specifiy 'ios::in'
    for type 'ifstream', since that 'mode' is its default.

    More important, you're trying to use an 'ifstream'
    object for output. Didn't your compiler complain?

    > char buf[10];


    What's this for?

    > std::string sample_buf;
    >
    > if(!sample || !outfile)


    Why not check the stream states immediately after opening,
    instead of creating a couple of objects first?

    > {
    > exit(0);


    Don't you think it would be more 'polite' to at least
    inform the user *why* the program abruptly halts?

    > }
    >
    > while(!sample.eof())


    You're misusing 'eof()' here. It does *not* return
    true until *after* an attempt to read past end of file.
    It does not 'predict' that the next read will encounter
    end of file.

    > {
    > sample.getline(const_cast<char*>(temp_buf.c_str()),30,'{');


    Wow, what malicious abuse of casting!! This is evidence
    that one should *really know* what one is doing before
    using a cast. 'std::string's member function 'c_str()'
    returns an array of *const* characters. Your cast does
    *not* change this fact. It's like driving your car
    toward a brick wall, and closing your eyes in the belief
    that if you don't see it, a collision will not occur.

    What you have above is 'undefined behavior'.

    Also, there is no 'temp_buf' defined at this scope.
    I simply don't believe your above statement that
    your code compiles.

    > outfile << temp_buf;


    Again, I see no definition for 'temp_buf'. Also,
    you have defined 'outfile' to be type 'ifstream'.
    There are no '<<' operators for type 'ifstream'.
    This is another statement the compiler should have
    diagnosed.

    >
    > }
    >
    > gets(buf);


    Ack! The Mortal Sin in C and C++ programming. *Never*,
    and I mean *never* use 'gets()'. Ever. Pretend it does
    not exist. There is absolutely *no way* to use it safely.

    Even if there were, you failed to provide its prototype
    from <cstdio> or <stdio.h>

    By, the way, why are you calling 'gets()' at all? You're
    not using what it stores.

    If you need to 'freeze' a graphical window containing your
    program so it won't 'close', just use:

    cin.get();

    >
    > return 0;
    > }


    Finally, to completely answer your question:

    std::getline(sample, sample_buf, '{');

    Input is stored directly into a 'std::string' object,
    no 'size' parameter needed (the 'std::string' will adjust
    its size as needed automatically), no dangerous
    arrays, no need to abuse casting, and a delimiter
    can be specified (defaults to '\n' if not).

    If the 'real' code you have does compile, copy
    and paste it here, don't retype it, so these
    kinds of 'spurious' errors don't waste your time
    and ours.

    A perusal of the 'C++ FAQ' should help you greatly:
    http://www.parashift.com/c -faq-lite/

    -Mike
    Mike Wahler, Aug 19, 2003
    #2
    1. Advertising

  3. "Kapil Khosla" <> wrote in message
    news:...
    > Hi,
    > I have a file with the format
    > //////////
    > {blkid:= 10000}
    > dfd dfd
    > dfdfdfd
    > dfd dfd
    > {blkid:= 10001}
    > dfd fddd
    > gdfd dd
    > dfdd
    > ere
    > ///////
    >
    > I want to set '{' as a delimiter and read everything between into a
    > std::string.
    > I checked out getline but it expects a "size", in my case I dont know
    > how big
    > will the buffer be so how should I solve this problem.


    You looked at the wrong getline

    getline(my_file, my_string, '}');

    john
    John Harrison, Aug 19, 2003
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy
    Replies:
    1
    Views:
    1,364
    J├╝rgen Exner
    Jan 20, 2004
  2. Maxim
    Replies:
    0
    Views:
    393
    Maxim
    Jul 7, 2003
  3. Long Le
    Replies:
    3
    Views:
    1,158
    Long Le
    Aug 11, 2004
  4. MWells
    Replies:
    2
    Views:
    408
    MWells
    Jan 11, 2005
  5. Hubert Hung-Hsien Chang
    Replies:
    2
    Views:
    406
    Michael Foord
    Sep 17, 2004
Loading...

Share This Page