Linked List and Input/Output Problems

I am having problems with a program that is supposed to take a list of data from an external .txt file, which the user inputs the name of the file, creates a linked list, and then outputs the data to another external .txt file, also which the user inputs the file name. Can anyone help me?
Here is my code:
The Specification File:
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
//**********************************
//* SPECIFICATION FILE (PetData.h) *
//**********************************

#ifndef PETDATA_H
#define PETDATA_H

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;
using namespace System;
using namespace System::IO;
using namespace System::Windows::Forms;
using namespace System::Runtime::InteropServices;

class PetData
{
public:

	//***************
	//* Constructor *
	//***************
	PetData( );

	//**********************************
	//* Create output file listing data*
	//**********************************
	void OutputItem( char* );

	void InsertItem( int, char*, PetData* );

	//*******************************************
	//* Return the value of the private members *
	//*******************************************
	int GetIDNumber( ) const;
	char* GetPetType( ) const;
	PetData* GetLink( ) const;

	//****************************************
	//* Set the value of the private members *
	//****************************************
	void SetIDNumber( int );
	void SetPetType( char [] );
	void SetLink( PetData* );

private:
	int IDNumber;
	mutable char PetType[25];
	mutable char OutputFile[50];
	mutable char InputFile[50];
	PetData* NextRecordPointer;
	
};

#endif 


The Implementation File:
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
//************************************
//* IMPLEMENTATION FILE (Retail.cpp) *
//************************************

#include "stdafx.h"
#include "PetData.h"

PetData* HeadPointer;

//***************
//* Constructor *
//***************
PetData::PetData()
{
	IDNumber = 0;
	PetType[25] = '\0';
	NextRecordPointer = NULL;
}


//************************************
//* Write the contents of the linked * 
//* list to an external report file  *
//************************************
void PetData::OutputItem( char* OutputFile )
{
	ofstream FileOut;
	PetData* CurrentRecordPointer;
	
	FileOut.open((char*)(void*)Marshal::StringToHGlobalAnsi(String::Concat(Directory::GetCurrentDirectory(),
		(OutputFile[50]))));

	
	//**********************************************************
	//* Records are listed until the NULL value is encountered *
	//**********************************************************
	CurrentRecordPointer = HeadPointer;
	while( CurrentRecordPointer != NULL )
		{
			FileOut << right;
			FileOut << endl << setw(5) << setfill(' ') 
				<< CurrentRecordPointer->GetIDNumber( );
			FileOut << setw(10) << setfill(' ')
				<< CurrentRecordPointer->GetPetType( );
			

			CurrentRecordPointer = CurrentRecordPointer->GetLink( );
		}

		FileOut.close( );
	return;
}

void PetData::InsertItem(int InitIDNumber, char InitPetType[], PetData* CurrentRecordPointer )
{
	ifstream DataFile;
			
			//*************************************
			//* Read first line of data           *
			//* Input Text File (Priming Reading) *
			//*************************************
			 DataFile >> InitIDNumber;
			 DataFile.ignore( );
			 DataFile.get( InitPetType, 7 );
			 while( DataFile )
			 {
				 CurrentRecordPointer = new PetData;
				 CurrentRecordPointer->InsertItem( InitIDNumber, InitPetType, CurrentRecordPointer );
				 HeadPointer = CurrentRecordPointer;

				 //***********************************************
				 //* Read next line of data from input text file *
				 //***********************************************
				 DataFile >> InitIDNumber;
				 DataFile.ignore( );
				 DataFile.get( InitPetType, 7 );
			 }
}


//*************************************************
//* Return the value of the private class members *
//*************************************************
int PetData::GetIDNumber( ) const
{
	return( IDNumber );
}

char* PetData::GetPetType( ) const
{
	return( PetType );
}

PetData* PetData::GetLink( ) const
{
	return NextRecordPointer;
}

//**********************************************
//* Set the value of the private class members *
//**********************************************
void PetData::SetIDNumber( int InitIDNumber )
{
	IDNumber = InitIDNumber;
}

void PetData::SetPetType( char* InitPetType )
{
	strcpy_s( PetType, InitPetType );
}

void PetData::SetLink( PetData* InitLink )
{
	NextRecordPointer = InitLink;
}


The stdafx.h file:

1
2
3
4
5
6
7
8
9
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
#pragma once

// TODO: reference additional headers your program requires here
#include "PetData.h"

extern PetData* HeadPointer;


The FinalProject.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// FinalProject.cpp : main project file.

#include "stdafx.h"
#include "Form1.h"

using namespace FinalProject;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew Form1());
	return 0;
}


The InputFile.txt file:

1
2
3
4
5
1 Dog
2 Cat
3 Bird
4 Fish
5 Lizard


Here is the part of the form1.h file that I coded:
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
	private: System::Void ExitButton_Click(System::Object^  sender, System::EventArgs^  e) {
				 
				 //********************
				 //* Exit the program *
				 //********************
				 Application::Exit();
				 return;
			 }


private: System::Void InputFileName_Click(System::Object^  sender, System::EventArgs^  e) {

			 //***********************************************
			 //* Clear text boxes and make message invisible *
			 //***********************************************
			 InputFileName->Clear();
			 OutputFileName->Clear();
			 CompletedMessage->Visible = false;
		 }



private: System::Void CreateFileButton_Click(System::Object^  sender, System::EventArgs^  e) {

			 PetData* CurrentRecordPointer;
			 int InitIDNumber = 0;
			 char InitPetType[25] = "\0";
			 ifstream DataFile;
			 ofstream FileOut;

			 //**********************************************************
			 //* Get the name entered and store in "InputFile" variable *
			 //**********************************************************
			 char* InputFile;
			 InputFile = (char*)(void*)Marshal::StringToHGlobalAnsi(InputFileName->Text);
			 DataFile.open( InputFile );
			 if( !DataFile )
			 {
				 Application::Exit();
			 }

			 //***********************************************************
			 //* Get the name entered and store in "OutputFile" variable *
			 //***********************************************************
			 char* OutputFile;
			 OutputFile = (char*)(void*)Marshal::StringToHGlobalAnsi(OutputFileName->Text);
			 FileOut.open( OutputFile );
			 if ( !FileOut )
			 {
				 Application::Exit();
			 }

			//**************************************
			 //* Calls function to read input data *
			 //*and add to linked list             *
			 //*************************************
			 HeadPointer->InsertItem( InitIDNumber, InitPetType, CurrentRecordPointer );

			 //*********************************
			 //* Calls function to output data *
			 //*********************************
			 HeadPointer->OutputItem( OutputFile );
			 CompletedMessage->Visible = true;


			 //****************************************
			 //* Delete/reset pointers and close file *
			 //****************************************
			 DataFile.close();
			 FileOut.close();
			 delete CurrentRecordPointer;
			 HeadPointer = NULL;
		 }
		 
};
}



Maybe specify what you need help with? Is this code already written for you and you simply have to modify certain sections of it?

Thanks,
Joe
www.concordspark.com
I'm having issues getting the output file to output the data from the linked list. When I get the program to use the names of the input and output files, I'm not getting the data in the output file. The code was not written for me.

Is anyone able to help me?
Last edited on
Is there anyone that can help me with this problem?
You need to pick a format for the file that is easy to read and easy to write. I suggest one line for each record with the ID first, followed by type. You can read it like this:
1
2
3
4
// is some istream:
is >> IDNumber;
getline(is, str);
strcpy(PetType, str.c_str());

and read it like this:
1
2
// os is some ostream
os << IDNumber << ' ' << PetType << '\n';


Next, you've made a common mistake of combining (1) the list itself and (2) the items within the list. You should have two separate classes for these.

Each function should do just one thing. Consider InsertItem. What you had to read the input from the terminal instead of a file? What if you had to insert an item that was read from a database? You'd have to refactor your code to accomplish either of these. That's why you should break it down:
- a method to read a PetData from an istream
- a separate method to insert a PetData into the list.
- The caller should create an ifstream for the input file and then use the method to read the list.

Here's what I mean:
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
/**********************************
 * SPECIFICATION FILE (PetData.h) *
 **********************************/

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>

using namespace std;

class PetData
{
  public:

    PetData();

    ostream &write(ostream &os);
    istream &read(istream &is);

    // *******************************************
    // * Return the value of the private members *
    // *******************************************
    int GetIDNumber() const;
    char *GetPetType() const;
    PetData *GetLink() const;

    // ****************************************
    // * Set the value of the private members *
    // ****************************************
    void SetIDNumber(int);
    void SetPetType(char[]);
    void SetLink(PetData *);

  private:
    int IDNumber;
    mutable char PetType[25];
    PetData *NextRecordPointer;

};

class PetList {
public:
    PetList() : HeadPointer(nullptr) {}
    ~PetList();
    
    ostream & write(ostream &os);
    istream & read(istream &is);


    // Insert a PetData instance. The PetList takes ownership
    // of the PetData
    void insert(PetData *data);
private:
    PetData *HeadPointer;
};
    


// ************************************
// * IMPLEMENTATION FILE (Retail.cpp) *
// ************************************


// ***************
// * Constructor *
// ***************
PetData::PetData()
{
    IDNumber = 0;
    PetType[25] = '\0';
    NextRecordPointer = NULL;
}

ostream &
PetData::write(ostream &os)
{
    os << IDNumber << ' ' << PetType << '\n';
    return os;
}


istream&
PetData::read(istream &is)
{
    string str;
    is >> IDNumber;
    getline(is, str);
    strcpy(PetType, str.c_str());
    return is;
}

// *************************************************
// * Return the value of the private class members *
// *************************************************
int
PetData::GetIDNumber() const
{
    return (IDNumber);
}

char *
PetData::GetPetType() const
{
    return (PetType);
}

PetData *
PetData::GetLink() const
{
    return NextRecordPointer;
}

// **********************************************
// * Set the value of the private class members *
// **********************************************
void
PetData::SetIDNumber(int InitIDNumber)
{
    IDNumber = InitIDNumber;
}

void
PetData::SetPetType(char *InitPetType)
{
    strcpy(PetType, InitPetType);
}

void
PetData::SetLink(PetData * InitLink)
{
    NextRecordPointer = InitLink;
}


istream &
PetList::read(istream &is)
{
    PetData tmp;
    while (tmp.read(is)) {
	insert(new PetData(tmp));
    }
    return is;
}

ostream &
PetList::write(ostream &os)
{
    for (PetData *p = HeadPointer; p; p = p->GetLink()) {
	p->write(os);
    }
    return os;
}

void PetList::insert(PetData *data)
{
    data->SetLink(HeadPointer);
    HeadPointer = data;
}

PetList::~PetList()
{
    PetData *next;
    while (HeadPointer) {
	next = HeadPointer->GetLink();
	delete HeadPointer;
	HeadPointer = next;
    }
}


int main()
{
    PetList theList;

    theList.read(cin);
    theList.write(cout);
    ofstream fs("output");
    theList.write(fs);
}

Topic archived. No new replies allowed.