need help with fstream

Started by
3 comments, last by n0rmanfreak 17 years, 11 months ago
hi! i'm missing something simply i guess...but i just don't see it :( why is my inputstream reading less chars than my output stream is writing ?? i'm using the same number of characters to read...can someone point me to what is going wrong...thx in advance

#include <fstream.h>
#include <stdio.h>

char name[3][40] = {"one", "two", "three"};
int a[3] = {1, 2, 3};
int b[3] = {11, 12, 13};


void load(fstream *index, fstream *data)
{
	printf("loading\n");
	char buf[40];
	int pos;
	while(index->good())
	{
		int idxPos = index->tellg();
		index->get(buf, 40);
		index->get((char*)&pos, sizeof(int));
		printf("%i -> %s %i\n", idxPos, buf, pos);
	}
	index->clear();
}

void saveDate(fstream *index, fstream *data, int i)
{
	int pos = data->tellp();
	printf("%s -> %i (%i, %i)\n", name, pos, a, b);

	data->write((char*)&a, sizeof(int));
	data->write((char*)&b, sizeof(int));

	int idxPos = index->tellp();
	printf("%i -> %i\n", idxPos, pos);
	index->write(name, 40);
	index->write((char*)&pos, sizeof(int));
	printf(" written... %i\n", index->tellp());
}

void save(fstream *index, fstream *data)
{
	index->seekp(0);
	printf("\n\nsaving\n");
	for(int i=0; i<3; i++)
		saveDate(index, data, i);

	data->flush();
	index->flush();
}

Advertisement
I believe You are using char to store the multi-letter values right? The char data type usually holds one character, not words or sentences. Try using string instead.
hi!

the char doesn't seem to be the problem...that's read properly.
the int is stored with 4 chars...i can also see that in the file. that seems to be some alignment....the input is just reading 2 chars for each int... but i'm using "sizeof(int)" in both cases ...any ideas?

thx
The problem is that get(char_pointer, n) will read n - 1 characters and then write a '\0' to the last element of the array. You should use read instead.

Your code is also fairly bad C++. Your example does not have enough context for me to know the best way to restructure it, but here are a few improvements. I am assuming that saving text data as fixed sized 40 character blocks is a deliberate design decision.
// There is no <fstream.h> in standard C++#include <fstream>// <stdio.h> and all the other standard C89 library headers are deprecated in// C++.  They are replaced by headers with the same names but no '.h' suffix and// a 'c' prefix.  This also puts all of their symbols into namespace std#include <cstdio>// C++ provides the string data type for textual data#include <string>std::string name[3] = {"one", "two", "three"};int a[3] = {1, 2, 3};int b[3] = {11, 12, 13};// Prefer to use named constants rather than magic numbersconst std::size_t savedTextLength = 40;// In C++ references are preferred to pointers since references cannot be nullvoid load(fstream & index, fstream & data){	// You're already using C++ I/O for files, why not for standard output	// too?	// printf("loading\n");	std::cout << "loading\n";	// When using fixed sized buffers in saved files there is no need to	// store the terminating zero.  This means we can use all 40 characters	// for text but when reading must remember to add a terminating zero.	// You may wish to store the terminating zero in the file for convenience	char buf[savedTextLength + 1] = {0};	int pos;	while (index.good())	{		int idxPos = index.tellg();		index.read(buf, savedTextLength);		// Use the four C++ casts to be more expressive about what it is		// you are doing		index.read(reinterpret_cast< char * >(&pos), sizeof(int));		// printf("%i -> %s %i\n", idxPos, buf, pos);		std::cout << idxPos << " -> " << buf << ' ' << pos << '\n';	}	index.clear();}void saveDate(fstream & index, fstream & data, int i){	int pos = data.tellp();	//printf("%s -> %i (%i, %i)\n", name, pos, a, b);	std::cout << name << " -> " << pos << " (" << a << ", " << b << ")\n";	data.write(reinterpret_cast< char * >(&a), sizeof(int));	data.write(reinterpret_cast< char * >(&b), sizeof(int));	int idxPos = index.tellp();	// printf("%i -> %i\n", idxPos, pos);	std::cout << idxPos << " -> " << pos << '\n';	name.resize(savedTextLength);	index.write(name.c_str(), savedTextLength);	index.write(reinterpret_cast< char * >(&pos), sizeof(int));	// printf(" written... %i\n", index->tellp());	std::cout << " written... " << index.tellp() << '\n';}void save(fstream & index, fstream & data){	index.seekp(0);	// printf("\n\nsaving\n");	std::cout << "\n\nsaving\n";	// always use braces, even for single line statements.  Doing so can	// prevent later errors when trying to add lines to the loop.	// Although it makes no difference here you should prefer preincrement	// to postincrement in C++ since it can be more efficient	for (int i = 0; i < 3; ++i)	{		saveDate(index, data, i);	}	data.flush();	index.flush();}

Σnigma
hi enigma!

thx for your fast and detailed answer :)

i replaced the get with the read method and it's working now...
about the fixed 40 characters i use that so i don't have to save the length of the string too...and have a faster/easier input.

This topic is closed to new replies.

Advertisement