File Processing

K

Kapil Khosla

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;
}
 
M

Mike Wahler

Kapil Khosla said:
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
 
J

John Harrison

Kapil Khosla said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,097
Latest member
RayE496148

Latest Threads

Top