Read from text file

#include <list>
#include <vector>
#include <queue>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

template <typename DataType>

class Digraph
{

};

//definition of Read()
template <typename DataType>
void Digraph<DataType>::Read(ifstream & inFile)
{
VertexInfo vi; //VertexInfo vi;
int n, //number of vertices adjacent to some vertex
vertex; //the nuber of vertex

v.push_back(vi); //garbage 0-th value so indices start with 1,as it
//customary
for(;;)
{
inFile>>vi.data;
if(inFile.eof()) break;
inFile>>n;

list<int> adjList; //construct empty list
for (int i =1; i <=n; i++)
{
inFile>>vertex;
adjList.push_back(vertex);
}
vi.adjacencyList=adjList;
v.push_back(vi);
}
}

int main()
{

cout<<"Enter network file: ";
string networkFile;
cin>>networkFile;

ifstream inFile(networkFile.data());
if (!inFile.is_open())
{
cerr << "***Cannot Open file " << networkFile<<" ***\n";
exit(-1);
}

Digraph<string> d;
d.Read(inFile);
cout<<"The Digraph's " ;
d.Print (cout);
cout << endl;

int start, destination;
char response;

do
{
cout<<"Number of Start node? ";
cin>>start;
cout<<"Number of destination node? ";
cin>>destination;

vector<int> path = d.ShortestPath(start,destination);
cout<<"Shortest path is: \n";

for (int k=0; k<path.size(); k++)
{
cout<<setw(3)<<path[k]<<' '<<d.Data(path[k])<<endl;
cout<<" |\n"
" V\n";
}
cout<<setw(3)<<destination<<' '
<<d.Data(destination)<<endl;
cout<<"More (Y or N)? ";
cin>> response;
}
while (response == 'y' || response == 'Y');
}

my problem is the file that I want to use (networkFile) to give the input did not pass to the Read function.
is there anything wrong with my code?
Last edited on
Please post your code using the code tags. It's the # symbol to the right on the format boxes, or just use "[code] *code goes here* [\code]".
I'll look at the code and comment if I can figure it out, just wanted to let you know to put it in the tags.
I'm getting a lot of errors when I try to compile the code. Is there more code for this program?
The class Digraph is empty so a load of errors turn up.
here is my full code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//Digraph Class Template

#include <list>
#include <vector>
#include <queue>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

template <typename DataType>

class Digraph
{
      //operation
      public: 
      DataType Data(int k) const; //number k of vertex,data value stored in vertex #k
      
      void Read(ifstream & inFile);  //input operator
      void Print(ostream & out);     //output operator
      void DepthFirstSearchAux(int start, vector <bool> & unvisited);     //depth firstof diagraph, starting at vertex start.
      void DepthFirstSearch(int start);
      //find a shortest path in the diagraph from vertex start to vertex destination 
      vector<int> ShortestPath(int start, int destination);   
      
      private:
              //head nodes of adjacency list
              class VertexInfo
              {     
                    public:
                           DataType data;
                           list<int> adjacencyList;
              };
      //data members
      vector<VertexInfo> v;
}; 
              
//definition of Data()
template <typename DataType>
inline DataType Digraph<DataType>::Data(int k) const
{
  return v[k].data;
}

//definition of Read()
template <typename DataType>
void Digraph<DataType>::Read(ifstream & inFile)
{
     VertexInfo vi;  //VertexInfo vi;
     int n,            //number of vertices adjacent to some vertex
         vertex;      //the nuber of vertex
                   
     v.push_back(vi); //garbage 0-th value so indices start with 1,as it customary
                   
     for(;;)
     {
            inFile>>vi.data;
            if(inFile.eof()) break;
            inFile>>n;
                          
            list<int> adjList;     //construct empty list
            for (int i =1; i <=n; i++)
            {
                inFile>>vertex;
                adjList.push_back(vertex);
            }
            vi.adjacencyList=adjList;
            v.push_back(vi);
     }
}
              
template <typename DataType>
void Digraph<DataType>::Print(ostream & out)
{
     out<<"Adjacency-List Representation: \n";
     for (int i=1; i < v.size(); i++)
     {
         out<<i<<":"<< v[i].data<<"--";
         for(list<int>::iterator it = v[i].adjacencyList.begin();
                                 it != v[i].adjacencyList.end(); it++)
           out<<*it<<" ";
         out<<endl;
     } 
}
              
//definition of DepthFirstSearch() and DepthFirstSearchAux()
template <typename DataType>
void Digraph<DataType>
::DepthFirstSearchAux(int start, vector<bool> & unvisited)
{
      //add statement here to process v[start].data
      cout<<v[start].data<<endl;
      unvisited[start] = false;
                    
      //traverse its adjacency list,performing depth-first searches from each unvisited vertex in it.
      for (list<int>::iterator
          it = v[start].adjacencyList.begin();
          it != v[start].adjacencyList.end(); it++)
                    
      //check if current vertex has been visited
      if (unvisited[*it])
         //start DFS from new node
         DepthFirstSearchAux(*it, unvisited);
}
              
template <typename DataType>
void Digraph<DataType>::DepthFirstSearch(int start)
{
     vector<bool> unvisited(v.size(), true);
     DepthFirstSearchAux(start, unvisited);
}
              
//definition of ShortestPath()
template<typename DataType>
vector<int> Digraph<DataType>::ShortestPath(int start, int destination)
{
     int n = v.size();               //number of vertices (#ed from 1)
     vector<int> distLabel(n, -1),   //distance labels for vertices, all marked as unvisited (-1)
     predLabel(n);                   //predecessor labels for vertices
                                      
     //perform breadth first search from Start to find destination,
     //labeling vertices with distance from start as we go.
     distLabel[start] = 0;
     int distance = 0,
         vertex;
         queue<int> vertexQueue;
         vertexQueue.push(start);
              
         while (distLabel[destination] < 0 && !vertexQueue.empty())
         {
               vertex = vertexQueue.front();
               vertexQueue.pop();
                    
               if (distLabel[vertex] > distance)
               distance ++;
                       
               for (list<int>::iterator it = v[vertex].adjacencyList.begin();
                                             it != v[vertex].adjacencyList.end(); it++)
               if (distLabel[*it]<0)
               { 
                 distLabel[*it] = distance+1;
                 predLabel[*it] = vertex;
                 vertexQueue.push(*it);
               }
         }
         distance++;
              
     //now reconstruct the shortest path if there is one 
     vector<int> path(distance+1);
     if(distLabel[destination]< 0)
     cout<< "Destination not reachable from start vertex\n";
     else
     {
         path[distance] = destination;
                  
         for (int k = distance-1; k >= 0; k--)
         path[k] = predLabel[path[k+1]];
     }
     return path;
}


//The program 

int main()
{
    
    cout<<"Enter network file: ";
    string networkFile;
    cin>>networkFile;
    
    ifstream inFile(networkFile.data());
    if (!inFile.is_open())
    {
       cerr << "***Cannot Open file " << networkFile<<" ***\n";
       exit(-1);
    }
    
    Digraph<string> d;
    d.Read(inFile);
    cout<<"The Digraph's " ;
    d.Print (cout);
    cout << endl;
    
    int start, destination;
    char response;
    
    do
    {
         cout<<"Number of Start node? ";
         cin>>start;
         cout<<"Number of destination node? ";
         cin>>destination;
         
         vector<int> path = d.ShortestPath(start,destination);
         cout<<"Shortest path is: \n";
         
         for (int k=0; k<path.size(); k++)
         {
             cout<<setw(3)<<path[k]<<' '<<d.Data(path[k])<<endl;
             cout<<"    |\n"
                   "    V\n";
         }
         cout<<setw(3)<<destination<<' '
             <<d.Data(destination)<<endl;
         cout<<"More (Y or N)? ";
         cin>> response;
    }
    while (response == 'y' || response == 'Y');
}


i can compile and run this coding, but the output seems to be incorrect..can anyone help me please
Last edited on
Please edit your post - there is a huge blank space after your last line asking for help.

I see that you are reading a file where each line is a string followed by an int followed by the required number of ints.
I made a file that looks like this:
Andy 5 1 3 5 7 9
John 5 2 4 6 8 10
Susan 5 1 2 3 4 5
Jim 5 5 4 3 2 1
Marcia 5 10 8 6 4 2
Marcus 5 9 7 5 3 1


It read that file ok.
Of course - I dont know what sort of values the vertex should have in order to make sense - so the shortest path function wouldn't work (program crashes) with my made-up values.

maybe if you provide a short example network file of data.
this is the example of networkFile content

Alice
2 3
Bob
1 3
Charlie
1 2

can you tell me the compiler that you used?
I am using the DevC++ compiler and I have try in Linux Fedora 8.
But both can't execute this code.

in the previous code my note :
..but the output seems to be incorrect..


Actually the output seems did not appear.
It only appear "Enter network file: "
After I have enter the networkFile name, the output did not appear.
I think that it cant read my text file.

Anyway..million thanks for you concern and help!!
That file setup you have is bad - it is causing an infinite loop with in the read function. The first line with Alice is the problem
Acccording to the way you have written the read function this is what is supposed to happen :

1. read a string (Alice).
2. read an integer (2).
3. The integer we read in step 2 tells us how many integers follows.
We are expecting 2 integers to follow but you only have 1 integer.
So the read function reads 1 integer but when it tries to read the second one it comes up against the string bob which it cannot read as an integer - the filestream is marked failed - so it keeps looping.
So change the first line to read something like
Alice 2 3 6 and it should be ok.

Do uou undertand what I mean??
Last edited on
By the way - this also has another side effect.
because it has failed to read the second vertex of Alice - the infile stream is marked as failed. the variable n has not been changed and will still holds 3 (it's current value).
The
1
2
            vi.adjacencyList=adjList;
            v.push_back(vi);

will push back Alice 3 3
You will then go back to the start of the endless loop for(;;)
and because the infile stream has failed - no new data will be read from the file so vertexInfo vi will still hold Alice 3 3 which will get push back - back to the top of the loop .........
If you leave this program running it will just fill up with Alice 3 3 and will most likely eventually crash.

You need to modify the read function to take file read failures into account (and if so - don't do the push back, possibly dump any previous push backs already done - and exit the read function cleanly)
ok..i have change my text file to something like this

Los_Angeles
3 3 4 6
San_Francisco
3 1 3 4
Denver
3 1 2 3
Chicago
2 3 8
Boston
2 4 6
New_york
3 4 7 8

and i have try to edit it like

Los_Angeles 3 3 4 6
San_Francisco 3 1 3 4
Denver
3 1 2 3
Chicago 2 3 8
Boston 2 4 6
New_york 3 4 7 8

both gave the same result.
And I can't have the Adjacency-List Representation output.
My output goes like:

Enter network file: networkFile.doc
The Digraph's Adjacency-List Representation:

Number of Start node?


Thanks once again!
Last edited on
fInally I got the output!

i just replace the .doc file to .txt file and it works well

thanks a bunch for your help and concern!!
Topic archived. No new replies allowed.