-
file reading
filename.get(char variable); Not Working.
Here's the code and file in my periodic table project.
The second loop isn't working eventhough I 'seekg'ed it to zero.
Neither is my sourcefile.getline() working.
First I thought that this is because I reached the end of file in the first loop. So I seekged it. But it is of no use >:
here's the file.
Code:
hydrogen|H|1|1|G
oxygen|O|8|16|G
sodium|S|11|23|S
Here's the code.
Code:
//header files included...
fstream sourcefile;
class Element{ //this class works fine I 'tested' it.
private:
char name[25], symbol[5], Z[8], M[8], state;
public:
Element(){
name[0] = symbol[0] = Z[0] = M[0] = state ='\0';
}
void set(char *na, char *sy, char *z, char *m, char s){
strcpy(name, na);
strcpy(symbol, sy);
strcpy(Z, z);
strcpy(M, m);
state = s;
}
void display(){
cout<<"\nElement :"<<name<<endl
<<"Symbol :"<<symbol<<endl
<<"Atomic No. :"<<Z<<endl
<<"Mass No :"<<M<<endl
<<"State :"<<state<<endl;
}
};
int main(){
clrscr();
sourcefile.open("ELEMENTS.txt", ios::in);
if(sourcefile){
int n;
char ch;
cout<<"pos :"<<sourcefile.tellg()<<endl;
for(n=0; sourcefile.get(ch); ){ //This is the first loop
cout<<ch; //This line was a tester only
if(ch == '\n')n++;
}
n++;
cout<<endl<<"n = "<<n<<endl;
Element *table = new Element[n];
cout<<"pos :"<<sourcefile.tellg()<<endl;
sourcefile.seekg(0, ios::beg);
cout<<"pos :"<<sourcefile.tellg()<<" (after seekg)\n";
for(; sourcefile.get(ch);)cout<<ch<<","; //this is loop No: 2
char na[25], sy[5], z[8], m[8], s;
for(int i=0; i<n; i++){
sourcefile.getline(na, 25, '\n');
cout<<"na :"<<na<<endl; //na is still an empty srting!!!
sourcefile.getline(sy, 5, '|');
sourcefile.ignore(1, '|');
sourcefile.getline(z, 8, '|');
sourcefile.ignore(1, '|');
sourcefile.getline(m, 8, '|');
sourcefile.ignore(1, '|');
sourcefile.get(s);
sourcefile.ignore(1, '\n');
table[i].set(na, sy, z, m, s);
table[i].display();
}
sourcefile.close();
// for(i=0; i<n; i++)table[i].display();
}else cout<<"Error opening file!!!\n";
getch();
return 0;
}
This is the output :
Code:
/*
pos =0
hydrogen|H|1|1|G
oxygen|O|8|16|G
sodium|S|11|23|S
n = 3
pos :51
pos :0 (after seekg)
na :
Element :
Symbol :
Atomic No:
Mass No :
State :
na :
Element :
Symbol :
Atomic No:
Mass No :
State :
na :
Element :
Symbol :
Atomic No:
Mass No :
State :
na :
*/
-
I suspect the stream is in the fail state after the first and second loop, because the terminating condition of each of the loops is that the stream isn't able to read anything into ch using get() anymore. I'd try putting a call to clear(), eg. sourcefile.clear();, to clear the fail bit after each of the first two loops. You might even have to reopen or reassociate the stream/file, too, but I don't think so.
-
cooooolllll
OK, if what you say is correct, how come many people use this method to reaf since it causes badbit in ios?
Thanks for the help. I'll try it...
I tried it & It was a fail bit!!!! :D :D :D :D
Thank a lot 'cause this would explain why many of my other projects were abandoned due to similar re-reading problems!!!
-
Take advantage of the string/vector containers and make use of overloaded stream insertion/extraction operators to clean up the code a bit:
Code:
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Element
{
private:
string name, symbol, Z, M, state;
public:
friend ostream& operator<<(ostream& os,const Element& elem);
friend istream& operator>>(istream& is,Element& elem);
};
istream& operator>>(istream& is,Element& elem)
{
getline(is,elem.name,'|');
getline(is,elem.symbol,'|');
getline(is,elem.Z,'|');
getline(is,elem.M,'|');
getline(is,elem.state);
return is;
}
ostream& operator<<(ostream& os,const Element& elem)
{
return os << "Element :" << elem.name
<< "\nSymbol :" << elem.symbol
<< "\nAtomic No. :" << elem.Z
<< "\nMass No :" << elem.M
<< "\nState :" << elem.state;
}
int main()
{
ifstream sourcefile("ELEMENTS.txt", ios::in);
vector<Element> elemVect;
if(sourcefile.is_open())
{
Element elem;
while( sourcefile >> elem ) elemVect.push_back(elem);
for( vector<Element>::iterator it = elemVect.begin(); it != elemVect.end(); ++it )
{
cout << *it << endl << endl;
}
}
else cout<<"Error opening file!!!\n";
cin.get();
return 0;
}
Output:
Code:
Element :hydrogen
Symbol :H
Atomic No. :1
Mass No :1
State :G
Element :oxygen
Symbol :O
Atomic No. :8
Mass No :16
State :G
Element :sodium
Symbol :S
Atomic No. :11
Mass No :23
State :S
-
I've never tried operator overloading with streams yet. Could you suggest a tut somewhere?