Hi,
My program reads data (text and int) from an input (notepad) file and stores it in a linked list.I then output the data in another file. No issues with compilation- as is, but the output text file doesn't correspond to the data from the input file (and crashes when too much data).
I know that my "buildlinkedlist function" has issues reading and storing the correct data. Any ideas on where I may have gone wrong here?
#include <iostream>
#include <fstream>
usingnamespace std;
struct Node {
int number;
char name;
Node* next;
};
typedef Node* NodePtr;
void AddToList (int NUM,char NAME, NodePtr &hdlist);
//Insert integer values into list and update hdlist
void BuildList ( char filename[16] , NodePtr &hdlist);
//Input file data, read and stored onto a list.
void output (NodePtr hdlist);
//Output data from linked list into text file
int getFromListNum (NodePtr &hdlist);
//Reads data from list and returns integer value
char getFromListChar (NodePtr &hdlist);
//Reads data from list and returns character value
int main (){
char FileName[16];
NodePtr hdlist= NULL;
cout<< "please enter the full name of the file you wish to create a linked list out of :\n";
cin>> FileName;
BuildList (FileName, hdlist);
output (hdlist);
}
void AddToList (int NUM, char NAME, NodePtr &hdlist) {
NodePtr newNode= new Node;
newNode->number= NUM;
newNode->name=NAME;
newNode->next= hdlist;
hdlist= newNode;
}
void BuildList ( char filename[16] , NodePtr &hdlist){
ifstream InputFile;
InputFile.open (filename);
int NUM=0;
char NAME=NULL, next;
InputFile.get(next);
while (!InputFile.eof()){
if (isdigit(next))
InputFile>>NUM;
else
InputFile>>NAME;
InputFile.get(next);
AddToList (NUM,NAME, hdlist);
}
}
int getFromListNum (NodePtr &hdlist) {
int NUM;
NUM = hdlist->number;
hdlist= hdlist->next;
return (NUM);
}
char getFromListChar (NodePtr &hdlist) {
char NAME;
NAME = hdlist->name;
hdlist= hdlist->next;
return (NAME);
}
void output (NodePtr hdlist){
ofstream OutputFile;
OutputFile.open("output1.txt");
while (hdlist !=NULL) {
OutputFile<<getFromListNum(hdlist)<<endl<<getFromListChar(hdlist)<<endl;
}
}
Here's a trail input text file:
r
1
s
d
Christos
w
9
The ouput that follows is:
0
9
0
w
0
s
0
C
0
s
I'm aware it's a lot of code- and may well require a perusal of the whole program- but, just to make the context clear, I thought it would be better to put it all there. Any suggestions would be very appreciated.
Let me just add, having read a response to another post on linked lists, that I have to create the linked lists from scratch.
1) Think about what happens when you have an input file name with 16 or more characters. You should look into std::string instead of using plain char arrays.
2) you have a "new", but no "delete". Where is the memory of "node" going to be freed? In C++, it's not considered polite to leave memory un-deleted and have the operating system free it after program termination. ;-)
3) You are implementing your own list structure, although there is a really simple-to-use in the standard library. Look up std::list or std::vector.
4) In BuildList, you are assuming a certain structure of the input file, e.g. it must not be empty). Your crashes may come from this.
But here the hint for what you are probably looking for:
5) In the while-loop of BuildList, you are adding both: NUM and NAME, but always reading only one of them - depending on the outcome of "isdigit(next)". Maybe you are confused how the operator>> (as in InputFile>>NUM) and the function ifstream::get (as in InputFile.get) work? (And that they both read input from the file and advance to the next position in the file.) Try some good tutorials on C++ file I/O. I am very sure there are a couple of these on this site somewhere.
Thanks for the suggestions Imi.
I have introduced a "delete linkedlist" function since your message. However, what exactly do you mean by saying that I assume a particular format for my Build List?
I only expect there to be Numbers and Text in the input file, but you feel that I should have a clause for exceptions outside this too?
I thought I'd read up enough on the C++ file I/O! Need to open up my books again...
iostream::get reads the next character from the stream and returns it.
iostream::operator>> also reads the next character(s) from the stream and assign them to the second parameter (what comes after the >>).
So you are basically reading a value in line 49 and another value (the next one) in line 53 or 55. You probably thinking, that get() only "peeks" into the stream and do not really read the value.
Also, remember that since NAME is a "char", it is only one character. If you want to read a full string, you have to use something else (where std::string is probably the easiest to look into if you are new to C++ and char[] the traditional choice for good old C-freaks..)