For which part?

btw, There's a way you can look for references too :)

I flip thru the books, but find it hard to implement. Examples I have here are very much different from what I want.

1) Need to know whether I can just go straight with the implementation using afile.open (filename, ios::in | ios::out |ios::binary);

2) But why the ios:binary? Because I strictly need the file to be in updateoutfile.txt

3) How is the function call like in int main () as I need to have an "outfile.dat" open for writing & "updateoutfile.txt" created?

For which part?

btw, There's a way you can look for references too :)

1.) I would just do ios::in | ios::binary

2.)You need the binary because you wrote it out in binary and you need to read it back in that way.

3.) If you can I'd create the fstream objects within their respective methods and not in main. For instance for your text out, make an fstream with ios::out and nothing else.

The "updateoutfile.txt" can be created & crash at the same time, the file contain nothing as I know that the last function was incorrectly done.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
using namespace std;

const int MAX = 20;
const int MAX1 = 30;

struct UKStudent
{
	char name [MAX1];
	int noTest;
	float mark [MAX];
	int final;
	char grade [MAX1];
};

struct OverseasStudent
{
	char country [MAX1];
	char name [MAX1];
	int noTest;
	float mark [MAX];
	int final;
	char grade [MAX1];
};

union EveryStudent
{
	UKStudent       uks;
	OverseasStudent	oss;
};

struct Student
{
	char type;   
	EveryStudent st;
};


int arraytofile (fstream&, char [], Student []);
void process_bintext (fstream&, char [], Student [],int);
void process_text (fstream&, char [], Student []);

int main()
{

	fstream afile;
	
	Student stu [MAX];
	
	int size = arraytofile (afile,"infile.txt",stu);
	process_bintext (afile,"outfile.dat", stu, size);
	process_text (afile, "outfile.dat", stu);

}

//Read infile.txt
int arraytofile (fstream& afile, char filename [], Student stu [])
{
    afile.open (filename, ios::in);
	
	if(!afile.good ())
	{
		cout << "The input file does not exist. " << endl;
		return 1;
	}
	
	char n;
	int i = 0;
	
	while (afile >> n)
	{
		switch (n)
		{
			case 'U': stu [i].type = n;
					  afile.getline (stu [i].st.uks.name,MAX);
					  break;
					
			case 'O': stu [i].type = n; 
					  afile.getline (stu [i].st.oss.country,MAX,' '); 
					  afile.getline (stu [i].st.oss.name,MAX);
					  break;
		}
		
		++i;
	}
	   
	
	afile.close ();
	return i;
}

//Convert infile.txt as binary file
void process_bintext (fstream& afile, char filename [], Student stu[], int size)
{
	afile.open (filename, ios::out | ios::binary);
	
	if(!afile.good())
	{
		cout <<"Failed to write file. " << endl;
		return;
	}
	
	
	char n;

	
	for (int i = 0; i < size; i++)
	{ 	   
			
			if (stu [i].type == n)
			{
				
				afile.write (&stu[i].type,1);
				afile.write (stu [i].st.uks.name,MAX); 
				
 			
			}
			else
			{
				
				afile.write(&stu[i].type,1);
 				afile.write (stu [i].st.oss.country,MAX); 
		    	afile.write (stu [i].st.oss.name,MAX); 
				
			}
				
			
	
	}	   	   
	
	afile.close ();
}

//Process binary file to text file
void process_text (fstream& afile, char filename [], Student stu[])
{
	afile.open (filename, ios::in | ios::binary);
	ofstream outfile ("updateoutfile.txt", ofstream::binary);
	
	if(!afile.good ())
	{
		cout << "Failed to update." << endl;
		return;
	}
	
	int i;	  
	//int n;
	//Student st;
	
	///afile.seekg (n-1) * sizeof (Student), ios::beg);
	afile.read (&stu[i].type,1);
	afile.read (stu [i].st.uks.name,MAX); 
	afile.read (stu [i].st.oss.country,MAX); 
    afile.read (stu [i].st.oss.name,MAX); 
	afile.read (stu [i].st.uks.grade,MAX1);
	
	for (int i = 0; i < MAX; i++)
	{ 	  
		
		//afile.write (&stu[i].type,1); 
		
		afile << i + 1 << endl;
		///afile.write (stu [i].st.oss.country,MAX);
		afile.write (reinterpret_cast <const char*> (&stu), sizeof (Student));
		
		
		//afile.write (stu [i].st.uks.name || stu [i].st.oss.name);
	    //afile.write (stu [i].st.uks.noTEST || stu [i].st.oss.noTEST);
		//afile.write (stu [i].st.uks.final);
		//afile.write (stu [i].st.uks.grade);
	}	 	 	 
			
		//afile.seekp (n-1) * sizeof (Student), ios::beg);	
			
	afile.close ();
	
}

If you file is text for your last function, why are you writing to it as a binary file? You can't mix << and write() or at least not for your desired result. So, open the outfile as text and write to it using << and your char arrays (which again, I remind you are not null terminated so implant a '\0' in a spot where you believe the characters have stopped.

If there's still a problem, put some cout statements in your program at strategic points (or use a debugger) and make sure all the values are being transferred in and out ok.

I am refering to void process_text() as the last function.
Really can't open the binary file & generate as text file in a single function? Tks.

If you file is text for your last function, why are you writing to it as a binary file? You can't mix << and write() or at least not for your desired result. So, open the outfile as text and write to it using << and your char arrays (which again, I remind you are not null terminated so implant a '\0' in a spot where you believe the characters have stopped.

If there's still a problem, put some cout statements in your program at strategic points (or use a debugger) and make sure all the values are being transferred in and out ok.

Check and make sure that you are not reading both the country of origin and the name into the 30 character array. I fixed the problem with a call to get() instead of a >> in the while loop condition and a .ignore() call afterward to get rid of the space between type and country.

I've managed to put in the '\0' characters in the proper place by using the gcount() method of the input stream, keeping an array of the character counts for name and country for each i.

Really can't open the binary file & generate as text file in a single function?

I don't believe so. Make life easier on yourself and use your new ofstream as text. I'm not sure what your hesitation is.

ofstream outfile ("updateoutfile.txt", ofstream::binary); is contradictory.

I can't continue right now. Kind of confusing now. Reading some notes now.

I still cannot do my function, void process_text()
Time is running out for me. Pls tell me in simple term how to get it working. Without it, I cannot proceed with the last function which is appending of record. TIA. :confused:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
using namespace std;

const int MAX = 20;
const int MAX1 = 30;

struct UKStudent
{
	char name [MAX1];
	int noTest;
	float mark [MAX];
	int final;
	char grade [MAX1];
};

struct OverseasStudent
{
	char country [MAX1];
	char name [MAX1];
	int noTest;
	float mark [MAX];
	int final;
	char grade [MAX1];
};

union EveryStudent
{
	UKStudent       uks;
	OverseasStudent	oss;
};

struct Student
{
	char type;   
	EveryStudent st;
};


int arraytofile (fstream&, char [], Student []);
void process_bintext (fstream&, char [], Student [],int);
void process_text (fstream&, char [], Student []);

int main()
{

	fstream afile;
	
	Student stu [MAX];
	
	int size = arraytofile (afile,"infile.txt",stu);
	process_bintext (afile,"outfile.dat", stu, size);
	process_text (afile, "updateoutfile.txt", stu);

}

//Read infile.txt
int arraytofile (fstream& afile, char filename [], Student stu [])
{
    afile.open (filename, ios::in);
	
	if(!afile.good ())
	{
		cout << "The input file does not exist. " << endl;
		return 1;
	}
	
	char n;
	int i = 0;
	
	while (afile >> n)
	{
		switch (n)
		{
			case 'U': stu [i].type = n;
					  afile.getline (stu [i].st.uks.name,MAX);
					  break;
					
			case 'O': stu [i].type = n; 
					  afile.getline (stu [i].st.oss.country,MAX,' '); 
					  afile.getline (stu [i].st.oss.name,MAX);
					  break;
		}
		
		++i;
	}
	   
	
	afile.close ();
	return i;
}

//Convert infile.txt as binary file
void process_bintext (fstream& afile, char filename [], Student stu[], int size)
{
	afile.open (filename, ios::out | ios::binary);
	
	if(!afile.good())
	{
		cout <<"Failed to write file. " << endl;
		return;
	}
	
	
	char n;

	
	for (int i = 0; i < size; i++)
	{ 	   
			
			if (stu [i].type == n)
			{
				
				afile.write (&stu[i].type,1);
				afile.write (stu [i].st.uks.name,MAX); 
				
 			
			}
			else
			{
				
				afile.write(&stu[i].type,1);
 				afile.write (stu [i].st.oss.country,MAX); 
		    	afile.write (stu [i].st.oss.name,MAX); 
				
			}
				
			
	
	}	   	   
	
	afile.close ();
}

//Process binary file to text file
void process_text (fstream& afile, char filename [], Student stu[])
{
	afile.open (filename, ios::in | ios::binary);
	
	
	if(!afile.good ())
	{
		cout << "Failed to update." << endl;
		return;
	}
	
	int i;	  
	char n;

		
	for (int i = 0; i < MAX; i++)
	{ 	  
			
			
		if (stu [i].type == n)
		{
		//afile.write (&stu[i].type,1); 
		//afile << i + 1 << endl;
		fstream outfile;
		outfile.open ("updateoutfile.txt", ios::out);
	
		afile.write (stu [i].st.oss.country);
		afile.write (stu [i].st.oss.name); 
		afile.write (stu [i].st.uks.name);
	    afile.write (stu [i].st.uks.noTEST);
		afile.write (stu [i].st.uks.final);
		afile.write (stu [i].st.uks.grade);
		
		afile.write (reinterpret_cast <const char*> (&stu), sizeof (Student));
		
		}while (afile >> n);

		
	}	 	 	 
					
	afile.close ();
	outfile.close ();	 
	
}

I told you repeatedly that you do not use write with text files and that is what you are doing on 164-171. Just to clarify, process_text is supposed to be reading in the binary file you wrote in the prior method, correct? We may have gotten signals crossed here.

Try them like outfile << stu [i].st.oss.country;

Ok. Yes, the process_text is gonna read in the binary file from process_bintext.

I told you repeatedly that you do not use write with text files and that is what you are doing on 164-171. Just to clarify, process_text is supposed to be reading in the binary file you wrote in the prior method, correct? We may have gotten signals crossed here.

Ok. Check out my edit to my last post. Check your output to make sure it's giving you what you want, but that's what I had been trying to explain to you. My sense is that without null termination cout will display a portion of the next string as well but I may be incorrect on this.

Still no output to updateoutfile.txt
Also, outfile << stu .st.uks.noTEST & outfile << stu .st.oss.noTEST;
cannot define.

/
//Process binary file to text file
void process_text (fstream& afile, char filename [], Student stu[])
{
	afile.open (filename, ios::in | ios::binary);
	ofstream outfile ("updateoutfile.txt", ofstream::binary);
	
	if(!afile.good ())
	{
		cout << "Failed to update." << endl;
		return;
	}
	
	int i;	  
	//int n;
	//Student st;
	
	///afile.seekg (n-1) * sizeof (Student), ios::beg);
	afile.read (&stu[i].type,1);
	afile.read (stu [i].st.oss.country,MAX); 
	afile.read (stu [i].st.uks.name,MAX); 
    afile.read (stu [i].st.oss.name,MAX);
	//afile.read (stu [i].st.uks.mark,MAX); 
	//afile.read (stu [i].st.oss.mark,MAX);
	//afile.read (stu [i].st.oss.final);
	//afile.read (stu [i].st.oss.final); 
	afile.read (stu [i].st.uks.grade,MAX1);
	afile.read (stu [i].st.oss.grade,MAX1);
	//afile.read (stu [i].st.uks.noTEST); 
	//afile.read (stu [i].st.oss.noTEST); 
	
	
	for (int i = 0; i < MAX; i++)
	{ 	  
		
		
		
		afile << i + 1 << endl;
		
		
		outfile << stu [i].st.oss.country;
		outfile << stu [i].st.uks.name;
		outfile << stu [i].st.oss.name;
		outfile << stu [i].st.uks.mark;
		outfile << stu [i].st.oss.mark;
		outfile << stu [i].st.uks.final;
		outfile << stu [i].st.oss.final;
		outfile << stu [i].st.uks.grade;
		outfile << stu [i].st.oss.grade;
		//outfile << stu [i].st.uks.noTEST;
	    //outfile << stu [i].st.oss.noTEST;
	}	 	 	 
		
		afile.write (reinterpret_cast <const char*> (&stu), sizeof (Student));	  
		//afile.seekp (n-1) * sizeof (Student), ios::beg);	
			
	afile.close ();
	
}

outfile << stu [i].st.uks.noTEST & outfile << stu [i].st.oss.noTEST; They are not defined anywhere in this method! You seemed like you were trying to read them in from the binary file but you didn't write anything like that into it. afile << i + 1 << endl; This is still wrong.

Do some cout statements between your read and output to text to make sure those variables were successfully read in with the Read() method.

outfile << i + 1 << endl; // This is for the running nos (1,2,3...etc), correct?

afile.read (stu [i].st.oss.country,MAX);
//cout << stu [i].st.oss.country;    Program Crash after inputting this line
afile.read (stu [i].st.uks.name,MAX); 
//cout << stu [i].st.uks.name;

Try them like outfile << stu [i].st.oss.country;

outfile << stu [i].st.uks.noTEST & outfile << stu [i].st.oss.noTEST; They are not defined anywhere in this method! You seemed like you were trying to read them in from the binary file but you didn't write anything like that into it. afile << i + 1 << endl; This is still wrong.

Do some cout statements between your read and output to text to make sure those variables were successfully read in with the Read() method.

outfile << i + 1 << endl; // This is for the running nos (1,2,3...etc), correct?

I'm not sure why you had it there but I gather you don't want to write them back out to your binary file again. That will write your number and then a newline before you write the other data.

Program Crash after inputting this line

Go back and make sure you're reading in the data in precisely the same order that you wrote it out, read doesn't know anything about your file except what you tell it (I want to write these bytes into wherever and the data structure is n bytes long). Failing that open up the binary file from which you are trying to read in a hex editor like Ancient Dragon had suggested.

Sorry, got any hint?

Go back and make sure you're reading in the data in precisely the same order that you wrote it out, read doesn't know anything about your file except what you tell it (I want to write these bytes into wherever and the data structure is n bytes long). Failing that open up the binary file from which you are trying to read in a hex editor like Ancient Dragon had suggested.

Sorry, got any hint?

For what??? Use multiple cout statements or a debugger to see what is in those variables. If it's not the right thing trace it backwards until it's right again. I will not spell out every last little detail for you to pick up. I am assisting you but I'm not your assistant.

I do not have or know how to use a debugger. Anyway, thanks for your help. :) Appreciate it alot.

I'm not sure why you had it there but I gather you don't want to write them back out to your binary file again. That will write your number and then a newline before you write the other data.


Go back and make sure you're reading in the data in precisely the same order that you wrote it out, read doesn't know anything about your file except what you tell it (I want to write these bytes into wherever and the data structure is n bytes long). Failing that open up the binary file from which you are trying to read in a hex editor like Ancient Dragon had suggested.

For what??? Use multiple cout statements or a debugger to see what is in those variables. If it's not the right thing trace it backwards until it's right again. I will not spell out every last little detail for you to pick up. I am assisting you but I'm not your assistant.

Is there anything to share here?

<deleted>

Is there anything to share here?

Nope -- that's why I deleted it. I deleted it because I answered post #40 before discovering it had already been answered.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.