CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Mar 2015
    Posts
    64

    Creating a text file for randomly generated numbers

    Hi guys. My code compiles, but it doesn't get past this:
    Name:  TextFileProblem.PNG
Views: 313
Size:  12.7 KB
    Here's the code:
    Code:
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    //ofstream random_numbers("randIntContainer.txt");
    ofstream random_numbers("D:/StudentData/Documents/DataStructures/SortingAlgorithms/randIntContainer.txt");
    void generateNumbers();
    
    int main()
    {	
    	
    
    	random_numbers.open("D:/StudentData/Documents/DataStructures/SortingAlgorithms/randIntContainer.txt");
    	if (random_numbers.fail())//Make sure file was created, and return an error if it wasn't.
    	{
    		cout << "Error opening \"randIntContainer.txt\" for output." << endl;
    		return 1;
    	}
    
    	cout << "\n\nPopulating randIntContainer.txt, please wait.\n";
    
    	//Populate separate file with 30 sets of 10, 20, 30, 40, 50, 60, 70, 80, 90,
    	//and 100 random numbers (which will total to 16500 random numbers):
    	generateNumbers();
    
    	cout << "\nNumbers written to randIntContainer.txt successfully!" << endl;
    	random_numbers.close();
    	return 0;
    }
    
    void generateNumbers()
    {
    	random_numbers.open("D:/StudentData/Documents/DataStructures/SortingAlgorithms/randIntContainer.txt");
    	int linecount = 1;
    	for (int i = 0; i < 16500; i++)
    	{
    		int randInt = rand() % 150 + 0;//generate random integer between 0 and 150
    		if (linecount % 10 == 0)
    			random_numbers << endl;
    		random_numbers << randInt << " ";//write the number to a text file
    		linecount++;
    	}
    	random_numbers.close();
    }

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: Creating a text file for randomly generated numbers

    You have:

    Code:
    ofstream random_numbers("D:/StudentData/Documents/DataStructures/SortingAlgorithms/randIntContainer.txt");
    That creates/opens the file.

    Then in main(), you try to open it again. That fails, which is why you get the error message.

    You are also opening/closing the file in generateNumbers().

    1) Why do you have the global ofstream variable ?

    2) I would remove the global variable and remove it from main().

    3) Create/use the ofstream object in generateNumbers() only:

    Code:
    void generateNumbers()
    {
    	ofstream random_numbers("D:/StudentData/Documents/DataStructures/SortingAlgorithms/randIntContainer.txt");
    	if (random_numbers.fail())
    	{
    		cout << "Error opening \"randIntContainer.txt\" for output." << endl;
    		return;
    	}
    Last edited by Philip Nicoletti; April 28th, 2015 at 09:38 PM.

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Creating a text file for randomly generated numbers

    //Populate separate file with 30 sets of 10, 20, 30, 40, 50, 60, 70, 80, 90,
    //and 100 random numbers (which will total to 16500 random numbers):
    Note that your generaeNumbers() code doesn't do this. It generate 1650 sets (where each set is on its own line in the file) of 10 random numbers (except first set which only has 9!).

    Why add 0 to randInt?

    You are also not seeding the random number generator before use.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Creating a text file for randomly generated numbers

    One possible way of generating these numbers is
    Code:
    void generateNumbers(ostream& os)
    {
    const unsigned int maxnum = 150;
    const unsigned int minnumset = 10;
    const unsigned int setinc = 10;
    const unsigned int maxnumset = 100;
    const unsigned int nosets = 30;
    const unsigned int nums = (maxnumset - minnumset + setinc) * (minnumset + maxnumset) / (2 * setinc);
    
    const static int init = (srand(time(NULL)), 0);
    
    	for (unsigned int s = 0; s < nosets; ++s)
    		for (unsigned int i = 0, linecount = 1, set = minnumset; i < nums; ++i)
    			os << rand() % maxnum << ((linecount++ % set) ? " " : (linecount = 1, set+=setinc, "\n"));
    }
    Last edited by 2kaud; April 29th, 2015 at 01:37 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Mar 2015
    Posts
    64

    Re: Creating a text file for randomly generated numbers

    It turns out you need to append a file in order to create it:
    Code:
    random_numbers.open("random_numbers.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    With that out of the way, I now want to format how the numbers are printed to the text file
    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    int randomrandom_numbersRW();
    
    int main()
    {
    	randomrandom_numbersRW();
    	
    	return 0;
    }
    
    int randomrandom_numbersRW()
    {
    	fstream random_numbers;
    	random_numbers.open("random_numbers.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return 1;
    	}
    	
    	cout << "\n\nPopulating randIntContainer.txt, please wait.\n";
    	int linecount = 1;
    	for (int i = 0; i < 16500; i++)
    	{
    		//formatting the text file:
    		int randInt = rand() % 150 + 0;//generate random integer between 0 and 150
    		if (linecount % 10 == 0)
    			random_numbers << endl;
    		random_numbers << randInt << " ";//write the number to a text file
    		linecount++;
                    //end of formatting the text file
    	}
    	random_numbers.close();	
    }
    Last edited by UncleBazerko; April 29th, 2015 at 06:38 PM. Reason: I was missing the append that creates the file for you.

  6. #6
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: Creating a text file for randomly generated numbers

    It turns out you need to append a file in order to create it:
    No. You only need to do that because you are specifying fstream::in (why are you doing that ??)
    Since you are using fstream:app, every time you run the program, data will be appended to the
    file if it already exists. You could have used fstream::trunc also.

    But .. why are you using fstream::in ? why are you using fstream instead of ofstream ?

    You could simply have used:

    Code:
    ofstream random_numbers("random_numbers.txt");
    This will create and open the file.

  7. #7
    Join Date
    Mar 2015
    Posts
    64

    Re: Creating a text file for randomly generated numbers

    Alright, with the text file problem solved, we're ready to focus on the bigger picture. My assignment instructions say that I'm supposed to populate a text file with enough random integers to fill 30 arrays for 10 different sizes (denoted by n), ranging from 10 to 100, which means a grand total of 16500 integers:

    30 * 10 = 300
    30 * 20 = 600
    30 * 30 = 900
    30 * 40 = 1200
    30 * 50 = 1500
    30 * 60 = 1800
    30 * 70 = 2100
    30 * 80 = 2400
    30 * 90 = 2700
    30 * 100 = 3000
    ______________________________
    16500

    When that's done, I'm supposed to read the integers in the text file, while simultaneously running all 4 sorting algorithms (selectionSort, bubbleSort, insertionSort, and quickSort) on each array in the 30-array-batches, while also keeping track of the total number of data swaps and comparisons, so that I can calculate the average data swaps and comparisons, and thus find out the efficiency of each sorting algorithm.

    Here's my code so far (my questions are in the comments):
    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    int generateNumbers(int& randInt);
    void readNumbers(int& randInt, int n, int arr[]);
    
    void selectionSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    void bubbleSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    void insertionSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    
    void swap(int arr[], int low, int high);
    int partition(int arr[], int low, int high, int& cmpCounts, int& numSwaps);
    void quickSort(int arr[], int low, int high, int& cmpCounts, int& numSwaps);
    
    void copyArray(int arr[], int arrCopy[], int n);
    void printSortingData(int randInt, int arr[], int n);
    
    fstream random_numbers;
    
    int main()
    {	
    	int randInt = 0;
    	int n = 10;
    	
    	int arr[n];//passed in from "int* arr = new int[n];" in readNumbers function
    	
    	int arrCopy[n];//passed in from "int* arrCopy = new int[n];" in copyArray function
    	
    	generateNumbers(randInt);
    	readNumbers(randInt, n, arr);
    	
    	int low = 0;
    	int high = n-1;
    	int cmpCounts = 0;
    	int numSwaps = 0;
    	//int cmpCountsSum[30];
    	//int numSwapsSum[30];
    	
    	copyArray(arr, arrCopy, n);	
    	selectionSort(arrCopy, n, cmpCounts, numSwaps);
    	//record the values of cmpCounts and numSwaps for the current arrCopy:
    	int* selSortSwapsSum = new int[swapsSum];	
    	if(i < 30)
    	{
    		selSortSwapsSum[i] = selSortSwapsSum[i+numSwaps];
    		//I already know that his will not work, because i is neither declared nor
    		//initialized in a for loop statement, but I don't want to loop either,
    		//because then I'll just populate the selSortSwapsSum array with the same
    		//numSwaps value 30 times. What should I do to solve this problem? Should I
    		//declare and populate this array of 30 numSwaps some place else?
    	}
    	else
    	{
    		delete [] selSortSwapsSum;
    	}
    	
    	int* selSortCmpsSum = new int[30];
    	if(j < 30)
    	{
    		selSortCmpsSum[j] = selSortCmpsSum[j+cmpSwaps];
    	}
    	else
    	{
    		delete [] selSortSwapsSum;
    	}
    		
    	
    	cmpCounts = 0;
    	numSwaps = 0;
    	
    	copyArray(arr, arrCopy, n);
    	bubbleSort(arrCopy, n, cmpCounts, numSwaps);
    	//record the values of cmpCounts and numSwaps for the current arrCopy:
    	
    	
    	cmpCounts = 0;
    	numSwaps = 0;
    	
    	copyArray(arr, arrCopy, n);
    	insertionSort(arrCopy, n, cmpCounts, numSwaps);	
    	//record the values of cmpCounts and numSwaps for the current arrCopy:
    	
    	
    	cmpCounts = 0;
    	numSwaps = 0;	
    	
    	copyArray(arr, arrCopy, n);
    	partition(arrCopy, low, high, cmpCounts, numSwaps);
    	quickSort(arrCopy, low, high, cmpCounts, numSwaps);
    	cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    	//record the values of cmpCounts and numSwaps for the current arrCopy:
    	
    	//printSortingData(randInt, arr, n);
    	
    	//with all 4 comparisons done, delete the arrays, so that arr can be recreated 
    	//as the next n-sized array in the 30 arrCopy batch:
    	delete [] arr;
    	delete [] arrCopy;
    	
    	return 0;
    } 
    
    int generateNumbers(int& randInt, int arr[])
    {	
    	random_numbers.open("random_numbers.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return 1;
    	}
    	
    	cout << "\nPopulating random_numbers.txt, please wait.\n";
    	
    	for (int i = 0; i < 300; i++)//it's going to be i < 16500 in the final code
    	{
    		randInt = rand()%100+0;//generate random integer between 0 and 100
    		random_numbers << randInt << " ";//write the number to a text file
    	}	
    	cout << "\nrandom_numbers.txt, was populated successfully.\n";	
    	random_numbers.close();
    	
    	/*
    	//copy ALL of the numbers from random_numbers.txt into an array
    	int i = 0;
    	int traverser = 0;
    	while((random_numbers >> randInt) && (i < n))
    	{
    			arr[i] = randInt;
    			i++;
    			traverser++;
    	}
    	cout << "We traversed through " << traverser << " numbers in the text file.\n";
    	*/
    }
    
    void readNumbers(int& randInt, int n, int arr[])
    {
    	random_numbers.open("random_numbers.txt", std::fstream::in);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return;
    	}
    	//copy the numbers from random_numbers.txt
    		
    	n = 10;
    	do{
    		for(int i = 0; i < 30; i++)
    		{
    			int* arr = new int[n];
    			for(int j = 0; j < n; j++)
    			{
    				arr[j] = randInt;
    				//when arr has n elements, pass it up to the main function, where a
     				//fresh arrCopy of it can be used for each one of the 4 sorting
    				//algorithms. How do I tell the program to do that?
    			}
    		}
    		n = (n+10);
    		//once we get the numSwaps and cmpCounts data from the current n-sized 30
    		//arrCopy batch, it's time to move up to the next n-size for the next 30
    		//arrCopy batch.
    	}while(random_numbers >> randInt);//while we have not yet reached the end (past the very last element) of the random_numbers.txt file	
    }
    
    void copyArray(int arr[], int arrCopy[], int n)//make a fresh copy of array arr[]
    {
    	int* arrCopy = new int[n];//error: declaration of int* arrCopy shadows a parameter
    	for (int i = 0; i < n; i++)
    	{
    		arrCopy[i] = arr[i];
    	}
    	//cout << "\nArray arr[] copied successfully.\n";
    }
    
    void selectionSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	int smallestIndex;
    	int smallest, saved;
    
    	for (int i = 0; i < n - 1; i++) {
    		// Find smallest element
    		smallest = arr[i];
    		smallestIndex = i;
    		
    		
    		for (int j = i + 1; j < n; j++) {
    			cmpCounts++;
    			if (arr[j] < smallest) 
    			{
    				numSwaps++;
    				smallest = arr[j];
    				smallestIndex = j;
    			}
    			
    		}
    		// Swap with smallest element
    		saved = arr[i];
    		arr[i] = arr[smallestIndex];
    		arr[smallestIndex] = saved;
    		numSwaps = (numSwaps+3);
    	}
    	cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    }
    
    
    void bubbleSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	for (size_t i = 0; i < n - 1; ++i)
    	{
    		for (size_t j = 0; j < n - i - 1; ++j)
    		{		
    			cmpCounts++;
    			if (arr[j] > arr[j + 1])
    			{
    				swap(arr[j], arr[j + 1]);
    				numSwaps++;
    			}
    		}
    	}
    	cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    }
    				
    
    void insertionSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	int firstOOO, j, temp;//firstOOO is short for "first out of order", j = element loc
    	
    	for(firstOOO = 1; firstOOO < n; firstOOO++)
    	{
    		if(arr[firstOOO] < arr[firstOOO - 1])
    		{
    			temp = arr[firstOOO];
    			j = firstOOO;
    			numSwaps++;
    			
    			do
    			{
    				cmpCounts++;
    				arr[j] = arr[j - 1];
    				j--;
    				numSwaps++;
    			}
    			while(j > 0 && arr[j - 1] > temp);
    			arr[j] = temp;
    		}		
    	}
    	cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    }//end of insertion sort
    
    void swap(int arr[], int i, int j)
    {
    	int temp = arr[i];
    	arr[i] = arr[j];
    	arr[j] = temp;
    }
    
    int partition(int arr[], int low, int high, int& cmpCounts, int& numSwaps)
    {
    	int i = low;
    	int j = high;
    	int x = arr[low];
    	while(i < j)
    	{
    		while(i < j && arr[j] > x) {
    			j--;
    			cmpCounts++;
    		}
    		swap(arr, i, j);
    		numSwaps++;
    
    
    		while(i < j && arr[i] <= x) {
    			i++;
    			cmpCounts++;
    		}
    		swap(arr, i, j);
    		numSwaps++;
    	}
    	return i;
    }
    
    void quickSort(int arr[], int low, int high, int& cmpCounts, int& numSwaps)
    {
    	if(low >= high || low < 0)//recursive base case
    	{
    		return;
    	}
    	int x = partition(arr, low, high, cmpCounts, numSwaps);
    	quickSort(arr, low, x-1, cmpCounts, numSwaps);
    	quickSort(arr, x+1, high, cmpCounts, numSwaps);
    }
    
    void printSortingData(int randInt, int arr[], int n)
    {
    	//the average number of swaps and comparisons for 30 arrays of size n were:
    	/*
    	selectionSort:
    	average numSwaps = (sum of all 30 array's numSwaps) / 30
    	average cmpCounts = (sum of all 30 array's cmpCounts) / 30
    	
    	bubbleSort:
    	average numSwaps = (sum of all 30 array's numSwaps) / 30
    	average cmpCounts = (sum of all 30 array's cmpCounts) / 30
    	
    	insertionSort:
    	average numSwaps = (sum of all 30 array's numSwaps) / 30
    	average cmpCounts = (sum of all 30 array's cmpCounts) / 30
    	
    	quickSort:
    	average numSwaps = (sum of all 30 array's numSwaps) / 30
    	average cmpCounts = (sum of all 30 array's cmpCounts) / 30
    	
    	*/
    }

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Creating a text file for randomly generated numbers

    I not sure I follow where you are attempting to go with your code as I don't think this has been thought through and designed before it was coded - which is often fatal!

    I'm also not sure what sort of output is expected from the program. However, one possible way of approaching this is as below (skeleton code for just bubble sort).

    Code:
    #include <sstream>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <ctime>
    #include <vector>
    #include <map>
    #include <algorithm>
    #include <utility>
    using namespace std;
    
    const string numfile = "numbers.txt";
    
    typedef pair<int, int> PII;
    
    struct results{
    	PII stats;
    	int sets;
    	results::results() : sets(0), stats{} {}
    };
    
    typedef map<size_t, results> MAPRES;
    
    PII bubbleSort(vector<int>& myarr);
    void generateNumbers(ostream& os);
    void update(MAPRES& res, size_t key, const PII& stat);
    istream& operator>>(istream& is, vector<int>& nos);
    ostream& operator<<(ostream& os, const MAPRES& mres);
    
    int main()
    {
    ofstream ofs(numfile.c_str());
    
    	if (!ofs.is_open()) {
    		cout << "Cannot open output file " << numfile << endl;
    		return 1;
    	}
    
    	generateNumbers(ofs);
    	ofs.close();
    
    ifstream ifs(numfile.c_str());
    
    	if (!ifs.is_open()){
    		cout << "Cannot open input file " << numfile << endl;
    		return 2;
    	}
    
    MAPRES bublestats;
    //MAPRES selecstats;
    vector<int> nums;
    
    	while (ifs >> nums) {
    		vector<int> sortnums(nums);
    		update(bublestats, nums.size(), bubbleSort(sortnums));
    
    		//and for the other sorts...
    		//sortnums = nums;
    		//update(selecstats, nums.size(), selectionSort(sortnums));
    		//...
    	}
    
    	cout << "Results for bubble sort...\n";
    	cout << bublestats << endl;
    
    	//cout << "Results for selection sort...\n";
    	//cout << selecstats << endl;
    
    	return 0;
    }
    
    void update(MAPRES& res, size_t key, const PII& stat)
    {
    	res[key].stats.first += stat.first;
    	res[key].stats.second += stat.second;
    	++res[key].sets;
    }
    
    istream& operator>>(istream& is, vector<int>& nos)
    {
    string line;
    
    	nos.clear();
    
    	if (getline(is, line)) {
    		stringstream ss(line);
    		int num;
    		while (ss >> num)
    			nos.push_back(num);
    	}
    
    	return is;
    }
    
    ostream& operator<<(ostream& os, const MAPRES& mres)
    {
    	for (const auto& bs : mres)
    		os << bs.second.sets << " sets of " << bs.first << " numbers. Swaps " << bs.second.stats.second << " comps " << bs.second.stats.first << endl;
    
    	return os;
    }
    
    void generateNumbers(ostream& os)
    {
    const unsigned int maxnum = 150;
    const unsigned int minnumset = 10;
    const unsigned int setinc = 10;
    const unsigned int maxnumset = 100;
    const unsigned int nosets = 30;
    const unsigned int nums = (maxnumset - minnumset + setinc) * (minnumset + maxnumset) / (2 * setinc);
    
    	const static int init = (srand((unsigned int)time(NULL)), 0);
    
    	for (unsigned int s = 0; s < nosets; ++s)
    		for (unsigned int i = 0, linecount = 1, set = minnumset; i < nums; ++i)
    			os << rand() % maxnum << ((linecount++ % set) ? " " : (linecount = 1, set += setinc, "\n"));
    }
    
    PII bubbleSort(vector<int>& myarr)
    {
    const size_t n = myarr.size();
    
    bool swapped;
    PII stats {};
    
    	do {
    		swapped = false;
    		for (size_t i = 0; i < n - 1; ++i) {
    			++stats.first;
    			if (myarr[i] > myarr[i + 1]) {
    				swap(myarr[i], myarr[i + 1]);
    				swapped = true;
    				++stats.second;
    			}
    		}
    	} while (swapped);
    
    	return stats;
    }
    This produces the output
    Code:
    Results for bubble sort...
    30 sets of 10 numbers. Swaps 625 comps 1989
    30 sets of 20 numbers. Swaps 2813 comps 8949
    30 sets of 30 numbers. Swaps 6552 comps 21692
    30 sets of 40 numbers. Swaps 11473 comps 38532
    30 sets of 50 numbers. Swaps 17843 comps 63014
    30 sets of 60 numbers. Swaps 26585 comps 92394
    30 sets of 70 numbers. Swaps 35629 comps 123579
    30 sets of 80 numbers. Swaps 46241 comps 166453
    30 sets of 90 numbers. Swaps 59767 comps 207815
    30 sets of 100 numbers. Swaps 73393 comps 266409
    Last edited by 2kaud; May 4th, 2015 at 03:40 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Mar 2015
    Posts
    64

    Re: Creating a text file for randomly generated numbers

    Quote Originally Posted by 2kaud View Post
    I not sure I follow where you are attempting to go with your code as I don't think this has been thought through and designed before it was coded - which is often fatal!
    How about now:
    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    int generateNumbers(int& randInt);
    void readNumbers(int& randInt, int n, int arr[]);
    
    void selectionSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    void bubbleSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    void insertionSort(int arr[], int n, int& cmpCounts, int& numSwaps);
    
    void swap(int arr[], int low, int high);
    int partition(int arr[], int low, int high, int& cmpCounts, int& numSwaps);
    void quickSort(int arr[], int low, int high, int& cmpCounts, int& numSwaps);
    
    void copyArray(int arr[], int arrCopy[], int n);
    
    void printSelectionSortData(int arr[], int arr2[], int n);
    void printBubbleSortData(int arr[], int arr2[], int n);
    void printInsertionSortData(int arr[], int arr2[], int n);
    void printQuickSortData(int arr[], int arr2[], int n);
    
    fstream random_numbers;
    
    int main()
    {	
    	int randInt = 0;
    	int n = 10;	
    	
    	int selSortnumSwapsSum[30];
    	int selSortcmpCountsSum[30];
    	
    	int bubSortnumSwapsSum[30];
    	int bubSortcmpCountsSum[30];
    	
    	int insSortnumSwapsSum[30];
    	int insSortcmpCountsSum[30];
    	
    	int quickSortnumSwapsSum[30];
    	int quickSortcmpCountsSum[30];
    
    	int i,j,x,y = 0;
    	
    	generateNumbers(randInt);
    	
    	/*
    	random_numbers.open("random_numbers.txt", std::fstream::in);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return;
    	}
    	*/
    	int totalArrayCount = 0;//10 sets of 30 arrays = 300 arrays total 	
    	while((totalArrayCount < 300) && (random_numbers >> randInt))
    	{
    		int* arr = new int[n];//int arr[n];	
    		int* arrCopy = new int[n];//int arrCopy[n];	
    		
    		readNumbers(randInt, n, arr);
    		
    		int low = 0;
    		int high = n-1;
    		int cmpCounts = 0;
    		int numSwaps = 0;
    		
    		copyArray(arr, arrCopy, n);	
    		selectionSort(arrCopy, n, cmpCounts, numSwaps);
    		//record the values of cmpCounts and numSwaps for the current arrCopy:
    		if(i < 30)
    		{
    			selSortnumSwapsSum[i] = numSwaps;
    			selSortcmpCountsSum[i] = cmpCounts;
    			i++;
    		}
    		else
    		{
    			printSelectionSortData(selSortnumSwapsSum, selSortcmpCountsSum, n);
    			delete [] selSortnumSwapsSum;
    			delete [] selSortcmpCountsSum;
    			int* selSortnumSwapsSum = new int[30];
    			int* selSortcmpCountsSum = new int[30];
    			i = 0;
    		}
    		
    		
    		cmpCounts = 0;
    		numSwaps = 0;
    		copyArray(arr, arrCopy, n);
    		bubbleSort(arrCopy, n, cmpCounts, numSwaps);
    		//record the values of cmpCounts and numSwaps for the current arrCopy:
    		if(j < 30)
    		{
    			bubSortnumSwapsSum[j] = numSwaps;
    			bubSortcmpCountsSum[j] = cmpCounts;
    			j++;
    		}
    		else
    		{
    			printBubbleSortData(bubSortnumSwapsSum, bubSortcmpCountsSum, n);
    			delete [] bubSortnumSwapsSum;
    			delete [] bubSortcmpCountsSum;
    			int* bubSortnumSwapsSum = new int[30];
    			int* bubSortcmpCountsSum = new int[30];
    			j = 0;
    		}
    		
    		
    		cmpCounts = 0;
    		numSwaps = 0;		
    		copyArray(arr, arrCopy, n);
    		insertionSort(arrCopy, n, cmpCounts, numSwaps);	
    		//record the values of cmpCounts and numSwaps for the current arrCopy:
    		if(x < 30)
    		{
    			insSortnumSwapsSum[x] = numSwaps;
    			insSortcmpCountsSum[x] = cmpCounts;
    			x++;
    		}
    		else
    		{
    			printInsertionSortData(insSortnumSwapsSum, insSortcmpCountsSum, n);
    			delete [] insSortnumSwapsSum;
    			delete [] insSortcmpCountsSum;
    			int* insSortnumSwapsSum = new int[30];
    			int* insSortcmpCountsSum = new int[30];
    			i = 0;
    		}
    		
    		
    		cmpCounts = 0;
    		numSwaps = 0;
    		copyArray(arr, arrCopy, n);
    		partition(arrCopy, low, high, cmpCounts, numSwaps);
    		quickSort(arrCopy, low, high, cmpCounts, numSwaps);
    		//record the values of cmpCounts and numSwaps for the current arrCopy:
    		if(y < 30)
    		{
    			quickSortnumSwapsSum[y] = numSwaps;
    			quickSortcmpCountsSum[y] = cmpCounts;
    			y++;
    		}
    		else
    		{
    			printQuickSortData(quickSortnumSwapsSum, quickSortcmpCountsSum, n);
    			delete [] quickSortnumSwapsSum;
    			delete [] quickSortcmpCountsSum;
    			int* quickSortnumSwapsSum = new int[30];
    			int* quickSortcmpCountsSum = new int[30];
    			y = 0;
    		}
    		
    		
    		
    		//with all 4 comparisons done, delete the arrays, so that arr can be recreated 
    		//as the next n-sized array in the 30 arrCopy batch:
    		delete [] arr;
    		delete [] arrCopy;
    		
    		if((totalArrayCount == 30) || (totalArrayCount == 60) || (totalArrayCount == 90)
    			|| (totalArrayCount == 120) || (totalArrayCount == 150)
    			|| (totalArrayCount == 180) || (totalArrayCount == 210)
    			|| (totalArrayCount == 240) || (totalArrayCount == 270))
    			{
    				n = (n+10);
    			}
    			totalArrayCount++;
    			
    	}//done iterating through random_numbers.txt	
    	
    	return 0;
    } 
    
    int generateNumbers(int& randInt, int arr[])
    {	
    	random_numbers.open("random_numbers.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return 1;
    	}
    	
    	cout << "\nPopulating random_numbers.txt, please wait.\n";
    	
    	for (int i = 0; i < 300; i++)//it's going to be i < 16500 in the final code
    	{
    		randInt = rand()%100+0;//generate random integer between 0 and 100
    		random_numbers << randInt << " ";//write the number to a text file
    	}	
    	cout << "\nrandom_numbers.txt, was populated successfully.\n";	
    	random_numbers.close();
    	
    
    void readNumbers(int& randInt, int n, int arr[])
    {
    	random_numbers.open("random_numbers.txt", std::fstream::in);
    	
    	if(!random_numbers.is_open())
    	{
    		cout << "Sorry, the file was not found.\n";
    		return;
    	}
    		for(int i = 0; i < n; i++)
    		{			
    			arr[i] = randInt;			
    		}	
    }
    
    
    void copyArray(int arr[], int arrCopy[], int n)//make a fresh copy of array arr[]
    {
    	for (int i = 0; i < n; i++)
    	{
    		arrCopy[i] = arr[i];
    	}
    	//cout << "\nArray arr[] copied successfully.\n";
    }
    
    void selectionSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	int smallestIndex;
    	int smallest, saved;
    
    	for (int i = 0; i < n - 1; i++) {
    		// Find smallest element
    		smallest = arr[i];
    		smallestIndex = i;
    		
    		
    		for (int j = i + 1; j < n; j++) {
    			cmpCounts++;
    			if (arr[j] < smallest) 
    			{
    				numSwaps++;
    				smallest = arr[j];
    				smallestIndex = j;
    			}
    			
    		}
    		// Swap with smallest element
    		saved = arr[i];
    		arr[i] = arr[smallestIndex];
    		arr[smallestIndex] = saved;
    		numSwaps = (numSwaps+3);
    	}	
    	//cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";		
    }
    
    
    void bubbleSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	for (size_t i = 0; i < n - 1; ++i)
    	{
    		for (size_t j = 0; j < n - i - 1; ++j)
    		{		
    			cmpCounts++;
    			if (arr[j] > arr[j + 1])
    			{
    				swap(arr[j], arr[j + 1]);
    				numSwaps++;
    			}
    		}
    	}
    	//cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    }
    				
    
    void insertionSort(int arr[], int n, int& cmpCounts, int& numSwaps)
    {
    	int firstOOO, j, temp;//firstOOO is short for "first out of order", j = element loc
    	
    	for(firstOOO = 1; firstOOO < n; firstOOO++)
    	{
    		if(arr[firstOOO] < arr[firstOOO - 1])
    		{
    			temp = arr[firstOOO];
    			j = firstOOO;
    			numSwaps++;
    			
    			do
    			{
    				cmpCounts++;
    				arr[j] = arr[j - 1];
    				j--;
    				numSwaps++;
    			}
    			while(j > 0 && arr[j - 1] > temp);
    			arr[j] = temp;
    		}		
    	}
    	//cout << "\n\nAfter " << cmpCounts << " comparisons, and " << numSwaps << " data movements, ";
    }//end of insertion sort
    
    void swap(int arr[], int i, int j)
    {
    	int temp = arr[i];
    	arr[i] = arr[j];
    	arr[j] = temp;
    }
    
    int partition(int arr[], int low, int high, int& cmpCounts, int& numSwaps)
    {
    	int i = low;
    	int j = high;
    	int x = arr[low];
    	while(i < j)
    	{
    		while(i < j && arr[j] > x) {
    			j--;
    			cmpCounts++;
    		}
    		swap(arr, i, j);
    		numSwaps++;
    
    
    		while(i < j && arr[i] <= x) {
    			i++;
    			cmpCounts++;
    		}
    		swap(arr, i, j);
    		numSwaps++;
    	}
    	return i;
    }
    
    void quickSort(int arr[], int low, int high, int& cmpCounts, int& numSwaps)
    {
    	if(low >= high || low < 0)//recursive base case
    	{
    		return;
    	}
    	int x = partition(arr, low, high, cmpCounts, numSwaps);
    	quickSort(arr, low, x-1, cmpCounts, numSwaps);
    	quickSort(arr, x+1, high, cmpCounts, numSwaps);
    }
    
    void printSelectionSortData(int arr[], int arr2[], int n)
    {
    	int numSwapsSum = 0;
    	for(int i = 0; i < 30; i++)
    	{
    		numSwapsSum += selSortnumSwapsSum[i];
    	}
    
    	cmpCountsSum = 0;
    	for(int j = 0; j < 30; j++)
    	{
    		cmpCountsSum += selSortcmpCountsSum[j];
    	}
    	
    	//selectionSort:
    	cout << "The average number of swaps for 30 arrays with " << n << " elements in them using selectionSort is: " << (numSwapsSum / 30) << endl;
    	cout << "The average number of comparisons for 30 arrays with " << n << " elements in them using selectionSort is: " << (cmpCountsSum / 30) << endl;
    }
    
    void printBubbleSortData(int arr[], arr2[], int n)
    {
    	int numSwapsSum = 0;
    	for(int i = 0; i < 30; i++)
    	{
    		numSwapsSum += bubSortnumSwapsSum[i];
    	}
    	
    	int cmpCountsSum = 0;
    	for(int j = 0; j < 30; j++)
    	{
    		cmpCountsSum += bubSortcmpCountsSum[j];
    	}
    	
    	//bubbleSort:
    	cout << "The average number of swaps for 30 arrays with " << n << " elements in them using bubbleSort is " << (numSwapsSum / 30) << endl;
    	cout << "The average number of comparisons for 30 arrays with " << n << " elements in them using bubbleSort is " << (cmpCountsSum / 30) << endl;
    }
    
    void printInsertionSortData(int arr[], arr2[], int n)
    {
    	int numSwapsSum = 0;
    	for(int i = 0; i < 30; i++)
    	{
    		numSwapsSum += insSortnumSwapsSum[i];
    	}
    	
    	int cmpCountsSum = 0;
    	for(int j = 0; j < 30; j++)
    	{
    		cmpCountsSum += insSortcmpCountsSum[j];
    	}
    	
    	//insertionSort:
    	cout << "The average number of swaps for 30 arrays with " << n << " elements in them using insertionSort is " << (numSwapsSum / 30) << endl;
    	cout << "The average number of comparisons for 30 arrays with " << n << " elements in them using insertionSort is " << (cmpCountsSum / 30) << endl;
    }
    
    void printQuickSortData(int arr[], arr2[], int n)
    {
    	int numSwapsSum = 0;
    	for(int i = 0; i < 30; i++)
    	{
    		numSwapsSum += quickSortnumSwapsSum[i];
    	}
    	
    	int cmpCountsSum = 0;
    	for(int j = 0; j < 30; j++)
    	{
    		cmpCountsSum += quickSortcmpCountsSum[j];
    	}
    	
    	//selectionSort:
    	cout << "The average number of swaps for 30 arrays with " << n << " elements in them using quickSort is " << (numSwapsSum / 30) << endl;
    	cout << "The average number of comparisons for 30 arrays with " << n << " elements in them using quickSort is " << (cmpCountsSum / 30) << endl;
    }
    I'm also getting lots of warnings about deleting arrays, and a couple weird curly brace errors that I shouldn't be getting. See for yourself:
    Name:  sortingAlgorithmsError3.jpg
Views: 210
Size:  49.0 KB

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Creating a text file for randomly generated numbers

    Code:
    int selSortnumSwapsSum[30];
    int selSortcmpCountsSum[30];
    ...
    delete [] selSortnumSwapsSum;
    delete [] selSortcmpCountsSum;
    int* selSortnumSwapsSum = new int[30];
    int* selSortcmpCountsSum = new int[30];
    selSortnumSwapsSum and selSortcmpCountsSum are defined as static arrays, not dynamic. So you shouldn't delete these or allocate memory to them.

    Code:
    cout << "\nrandom_numbers.txt, was populated successfully.\n";	
    random_numbers.close();
    }
    You have missed the function body closing }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  11. #11
    Join Date
    Oct 2013
    Posts
    10

    Re: Creating a text file for randomly generated numbers

    Nice try. I suggest you to keep the code simple as you can. As above member mentioned you have missed the function body closing bracket. here is a simple code of c which may help you it is basic code: write data into a text file c++ program
    A simple way to create file and add data into it. thats all. hope it will be helpful
    Blogging at C++ programming for beginners to help students

  12. #12
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Creating a text file for randomly generated numbers

    Quote Originally Posted by fahadmunir32 View Post
    Nice try. I suggest you to keep the code simple as you can. As above member mentioned you have missed the function body closing bracket. here is a simple code of c which may help you it is basic code: write data into a text file c++ program
    A simple way to create file and add data into it. thats all. hope it will be helpful
    Please don't necro an old thread when you don't really have anything new to contribute, just to link to your blog.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured