File Processing

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kapil Khosla

    File Processing

    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_da ta.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.d at",ios::out) ;
    char buf[10];
    std::string sample_buf;

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

    while(!sample.e of())
    {
    sample.getline( const_cast<char *>(temp_buf.c_s tr()),30,'{');
    outfile << temp_buf;

    }

    gets(buf);

    return 0;
    }
  • Mike Wahler

    #2
    Re: File Processing

    Kapil Khosla <khoslakapil@ya hoo.com> wrote in message
    news:919aa2da.0 308182258.2c434 93e@posting.goo gle.com...[color=blue]
    > 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.[/color]

    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.
    [color=blue]
    > I have attached
    > a sample code which compiles[/color]

    I see at least a few things that I think should prevent it
    from compiling. See below.
    [color=blue]
    >but does not give me the string I expect.
    > Can you help.
    > Thanks.
    > Kapil
    > // semantics_of_da ta.cpp : Defines the entry point for the console
    > application.
    > //
    >
    > #include "stdafx.h"[/color]

    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.
    [color=blue]
    > #include <iostream>
    > #include <fstream>
    > #include <string>
    >
    > using namespace std;
    >
    > int _tmain(int argc, _TCHAR* argv[])[/color]

    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.
    [color=blue]
    > {
    > ifstream sample("sample. dat",ios::in);
    > ifstream outfile("temp.d at",ios::out) ;[/color]

    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?
    [color=blue]
    > char buf[10];[/color]

    What's this for?
    [color=blue]
    > std::string sample_buf;
    >
    > if(!sample || !outfile)[/color]

    Why not check the stream states immediately after opening,
    instead of creating a couple of objects first?
    [color=blue]
    > {
    > exit(0);[/color]

    Don't you think it would be more 'polite' to at least
    inform the user *why* the program abruptly halts?
    [color=blue]
    > }
    >
    > while(!sample.e of())[/color]

    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.
    [color=blue]
    > {
    > sample.getline( const_cast<char *>(temp_buf.c_s tr()),30,'{');[/color]

    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.
    [color=blue]
    > outfile << temp_buf;[/color]

    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.
    [color=blue]
    >
    > }
    >
    > gets(buf);[/color]

    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();
    [color=blue]
    >
    > return 0;
    > }[/color]

    Finally, to completely answer your question:

    std::getline(sa mple, 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:


    -Mike





    Comment

    • John Harrison

      #3
      Re: File Processing


      "Kapil Khosla" <khoslakapil@ya hoo.com> wrote in message
      news:919aa2da.0 308182258.2c434 93e@posting.goo gle.com...[color=blue]
      > 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.[/color]

      You looked at the wrong getline

      getline(my_file , my_string, '}');

      john


      Comment

      Working...