Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Read In From File

Status
Not open for further replies.

Xign

Programmer
Dec 4, 2005
6
GB
Hi guys.

I'm rying to read in from a text file. The text file is formatted like this:

author ;title ;category;number
(there are 28 lines)

How can i read this data into 4 user defines variables, using an array? i am using this code:

BookData a[MAX] ;
int Read = 0 ;

do
{
file.get(a[Read].author, 26) ;
file.get(a[Read].title, 32) ;
file.get(a[Read].category, 3) ;
file >> a[Read].booknumber ;
Read++ ;
}
while (file) ;

but the lines seem to skip, so for instance on the second line, it misses data, and starts reading 8 character is.

Can you pleasseeee help!

thanks.
 
OK, first of all, are the fields fixed length or just semicolon delimited?
From your code I'm assuming it's fixed length fields.
I'm also assuming that 'file' is an ifstream object.

Try using something like this:
Code:
char bookBuf[ largestLineSize ];
...
file.getline( bookBuf, largestLineSize, '\n' );

// Then parse out the author, title, category & book # from bookBuf and put them in your array.
You should also consider switching your array to a vector<BookData> at some point.
 
A tohught that :D

cheers m8 - yea there fixed length, 78 characters long.

thanx mate :D

Xign
 
OK new problem, as im trying to move this data to seperate variables, the "author" works but the title, category, and number dont.

i was going to use "for loops", is there a better way of doing this cos this is totally stumping me!

Thanks guys
 
What code are you using now? What is it doing?
 
I'm using the above method, with a for loop to read in each different variable.

However what its doing is displaying the files wrong, so when i store the tit variable, it some how affects the author variable.

I'm gonna continue playing, maybe try some form of while loop too.
 
im using this sort of code and i keep getting "segmentation error"

do
{
file.getline(book, LARGEST, '\n') ;

for (int i = 0; i <= 24; i++)
{
a[Read].author = book[Count] ;
Count++ ;
}
for (int i = 0; i <= 30; i++)
{
a[Read].title = book[Count] ;
Count++ ;
}
Read++ ;
} while (file) ;

t'is driving me mad!
 
The line:
Code:
} while ( file );
won't test for EOF, it should just go on forever.

Here's what I would do:
Code:
struct Book
{
	string author;
	string title;
	string category;
};

int main()
{
	ifstream file( "c:\\file.txt" );

	if ( !file )
	{
		cout << endl << "Error opening file!" << endl;
		return 1;
	}

	size_t			read	= 0;
	string			book;
	vector<Book>	a;
	Book			temp;

	do
    {
		getline( file, book );
		int i = 0;

		temp.author = book.substr( 0, 24 );
		temp.title = book.substr( 26, 30 );
		// Do the same for all other fields...

		a.push_back( temp );

		++read;
    }  while ( file.eof() == false );

	vector<Book>::iterator it = a.begin();

	for ( ; it != a.end(); ++it )
	{
		cout << endl << "Author:   " << it->author
			 << endl << "Title:    " << it->title << endl;
	}

	exit 0;
}
 
while (file) (if a file is a C++ istream) works fine and detects EOF (and errors) on the stream. There is stream-to-bool conversion in the C++ STL...
 
Must be a problem with my crappy VC 6.0 STL then...
 
I got it working now guys! thanx for the help :D
 
Oh, sorry, some additions... while (file) works fine in VC++ 6.0 STL, but after eof condition raised (try to read after EOF). Alas, in all snippets above (do ... while) loop body tries to read and process data w/o any eof checking, so you may get eof (no data) then process previously initialized (or non-initialized) BookData, Book etc.

It's a common logic error. Be careful: do...while loop is a harmful thing. Better use pattern
Code:
while (getline(file,book)
{
   // You have a book!
}
getline() returns istream& then stream-to-bool conversion yields true (no eof or errors) or false - that's OK...
 
h, sorry, some additions... while (file) works fine in VC++ 6.0 STL, but after eof condition raised (try to read after EOF). Alas, in all snippets above (do ... while) loop body tries to "

This is a C++ in unix forum ;)
 
C++ == C++ on Unix, Windows, in Africa etc. It's not platform-dependend issue.
 
The problem is that it doesn't know it's done until he tries to read again at the top of the loop. The correct thing to do is to check for error on each read, but an alternitive it so use peek() in the while()... That way, if there is an extra return or not, you'll still be safe
Code:
  while(file && file.peek() != EOF)
  {
    [red]...[/red]
  }
OR
Code:
 do{
  [red]...[/red]
 }while(file && file.peek() != EOF)
OR (better and more proactive)
Code:
 do
    {
      file.getline(book, LARGEST, '\n') ;
      [green]if(!file) 
        break;[/green]
      for (int i = 0; i <= 24; i++)
        {
          a[Read].author[i] = book[Count] ;
          Count++ ;
        }
      for (int i = 0; i <= 30; i++)
        {
          a[Read].title[i] = book[Count] ;
          Count++ ;
        }
      Read++ ;
    }  while (file) ;

Oh, and don't mix >> and getline(...) as getline will leave extra stuff on the stream. If you >> or getline on a stream, best not to use the other. The way I found to mix them is if your using newlines as delim, then read a blank line from the stream to grab the left overs...

while (file) (if a file is a C++ istream) works fine and detects EOF (and errors) on the stream. There is stream-to-bool conversion in the C++ STL...

The reason this works is because in a pointer dereference or cast, the standard says that it must use the first n bytes of the variable to cast to the type your trying to cast to... If it's a valid cast, then the sizes match. In the case of a class or struct it uses the first thing defined so:
Code:
[red]...[/red]

struct thing
{
  bool a
  thing(){a = 100;}
  int method(int b){//some method}
  long lalalala
} fred;

[red]...[/red]

int main()
{
  [green]bool z = (bool)fred;[/green]   //casts fred to a bool, 
                         //exactly equal to thing->a
  [green]int y = (int)fred;[/green]     //casts fred to an int
                         //exactly equal to (int)thing->a
                         //100
 [red]string s = (string)fred;[/red] //shouldn't compile 
                         //because bool isn't castable 
                         //to a string

  return -1;
}

[plug=shameless]
[/plug]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top