Skip to main content
GameDev.net gamedev.net
🔒 Locked

fstream simple question

Started by d3x Apr 11, 2006 at 3:03 AM 10 replies 850+ views
Original Post
d3x
d3x
i am trying to read a txt file using fstream fstream myfile("code.dat"); code.dat looks like this A BCDEF B CC C XXAA D W E . H and so on. every letter has its own code (letter A is BCDEF) I want to read these code into a structure i have created. struct structKodovi { char* cSlovo; char* cKod; }; so I do it like this: struct structKodovi Kodovi[28]; //28 lines in code.txt //reserve space for all letters and codes for (int =0;n<28;n++) { Kodovi[n].cKod = new char[5]; //code is maximum 5 chars Kodovi[n].cSlovo= new char; //leter is one char :) } /* now i read from code.dat -first i read first character on every line of txt (first is A) -then i seek +1 because i want to get the code -and then i read 5 characters of code (for A this is BCDEF) the programs reads A and BCDEF and puts it into Kodovi[0].cSlovo and Kodovi[0].cKod but there are 27 more codes to be read. I want the cursor to go to next line so i can read letter B and it's code into Kodovi[1] and so on... when it finishes reading first line tellg becomes -1 that means end of file. why? what am i doing wrong? I tried using getline insted, but the same happens. reads the first line of txt file and tellg becomes -1 and it doesnt read next lines of txt. Kodovi should be an array of structures where Kodovi[0] contains A and its code, Kodovi[1] B and its code and so on... */ for (int i=0;i<28;i++) { fKod.get(Kodovi.cSlovo, 2); fKod.seekg(ios::cur,+1); fKod.get(Kodovi.cKod, 6); }
Aardvajk
Aardvajk
struct Kodovi{string Slovo;string Kod;}Kodovi K[28];fstream fs(whatever);for(int i=0;i<28;++i){    fs >> K.Slovo >> K.Kod;}


Putting an ostream to a string ignores whitespace.
smart_idiot
smart_idiot
#include <iostream>#include <fstream>#include <map>#include <string>std::map<char, std::string> Kodovi;void read(const std::string &filename) {  std::ifstream file(filename.c_str());    std::string line;    while(std::getline(file, line)) if(line.size() >= 2 && line[1] == ' ')   Kodovi[line[0]] = line.substr(2); }int main() {  read("code.dat");    for(char c = 'A'; c <= 'E'; ++c)   std::cout << c << " = \"" << Kodovi[c] << '"' << std::endl; }
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other
d3x
d3x
but why is this happening? because of char*?
Aardvajk
Aardvajk
You'd need to post the actual code, but unless you are genuinely interested from a purely academic point of view I'd go with smart_idiot and the STL.
d3x
d3x
the code is compiled in vc++2003


#include <iostream>#include <fstream>using namespace std;ifstream fCode("code.dat");struct structCodes{	char* cLetter;	char* cCode;};struct structCodes Codes[28];void getCodes(){		for (int n=0;n<28;n++)	{		Codes[n].cLetter = new char[5];		Codes[n].cCode   = new char;	}					if (!fCode.is_open())	{		cout << "Unable to open code.dat!";		fCode.close();		fCode.clear();		return;	}		while (fCode.tellg()>=0)	{	for (int i=0;i<28;i++)		{			fCode.getline(Codes.cLetter, 2);			fCode.seekg(ios::cur, +2);			fCode.getline(Codes.cCode, 6);						}		}}int main(){		getCodes();	system("PAUSE");	return 0;}




the code.dat is

A BCDEFB CCC XXAAD WE . HF .ABG XYWH ABCDEI ACDEFJ . ACDK POLOPL LILIM MONON LOPOO POPOP MIRANQ HIJKLR TREBAS TIPT SLOGAU PROBAV IIIW FCADEX FBAY FFAZ KLM  ZZZ. TA
smart_idiot
smart_idiot
c strings require extra space for a null character. So if the longest string is 5 characters, you need to allocate 6 bytes. For the single character string, you need 2 bytes, not 1.

Seeking ahead 2 characters is redundant. After you read something, the stream is automatically advanced (with the exception of some functions that can peek at the input buffer without actually removing anything, but you're unlikely to use them any time soon).

The c string version of getline will only store n characters in the string, but it still reads all the way to the delimiting character, '\n' being the default. To read only up to the space, pass a ' ' as the delimiting character.

Insert the obligitory statement about how c strings are evil here.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other
Tradone
Tradone
Just an idea.
using a map container and the boost::serialization seems like it can get your job done in literally 20 seconds.
Aardvajk
Aardvajk
Also, putting the while loop around the for loop is almost certainly not what you mean.

I notice some of the second bits in your data file ". ACD" etc also have spaces in. This is going to be a nightmare to scan like this. Maybe you should be reading in a whole line at a time and then splitting it in two once you have it in memory.

Use std::string though. Much wailing and gnashing of teeth will be saved.
d3x
d3x
wow its so much easier to work with std::string.

i wrote a new program in minutes.

thank you all very much for these great explanations.
CrazyCdn
CrazyCdn
also:

if (!fCode.is_open())
{
cout << "Unable to open code.dat!";
fCode.close();
fCode.clear();
return;
}

Why try and close something that is not open anyways? Doubt it would cause problems (never done it so don't know) but still.
"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.