I am trying to sort a file based on the users choice of 2 files. I'm using a string variable and passing it into the instream()
but it keeps going into the if
statement that says the file is corrupt or does not exist. I know it exists because when I hardcode the file name in then it works perfectly fine! I'm sure its something simple but I just can't figure it out. I'm very new to c++ so please be thorough with your answers so that I can understand and learn. Thanks in advance!
#include <iterator>
#include <algorithm>
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
std::string file = "";
std::ofstream out("outputfile.txt");
std::vector<int> numbers;
std::string sortType = "";
void sort(std::vector<int>);
void MergeSort(vector<int> &numbers);
int main()
{
std::cout << "Which type of sort would you like to perform(sort or mergesort)?\n";
std::cin >> sortType;
std::cout << "Which file would you like to sort?\n";
std::cin >> file;
std::ifstream in(file);
//Check if file exists
if(!in)
{
std::cout << std::endl << "The File is corrupt or does not exist! ";
return 1;
}
// Read all the ints from in:
std::copy(std::istream_iterator<int>(in), std::istream_iterator<int>(),
std::back_inserter(numbers));
//check if the file has values
if(numbers.empty())
{
std::cout << std::endl << "The file provided is empty!";
return 1;
} else
{
if(sortType == "sort")
{
sort(numbers);
}else
{
MergeSort(numbers);
}
// Print the vector with tab separators:
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\t"));
std::cout << std::endl;
// Write the vector to a text file
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(out, "\t"));
std::cout << std::endl;
}
return 0;
}
void sort(std::vector<int>)
{
// Sort the vector:
std::sort(numbers.begin(), numbers.end());
std::unique(numbers.begin(), numbers.end());
return;
}
vector<int> Merge(vector<int> &left, vector<int> &right)
{
std::vector<int> result;
while (left.size() > 0 && right.size() > 0)
{
if (left[0] <= right[0])
{
result.push_back(left[0]);
left.erase(left.begin());
} else
{
result.push_back(right[0]);
right.erase(right.begin());
}
}
if (left.size() > 0)
{
result.insert(result.end(), left.begin(), left.end());
} else
{
result.insert(result.end(), right.begin(), right.end());
}
return result;
}
void MergeSort(vector<int> &numbers)
{
if (numbers.size() <= 1)
{
return;
}
// split vector into two peices
vector<int> left, right;
unsigned int Middle = numbers.size() / 2;
for (unsigned int i = 0; i < Middle; i++)
{
left.push_back(numbers[i]);
}
for (unsigned int i = Middle; i < numbers.size(); i++) {
right.push_back(numbers[i]);
}
MergeSort(left);
MergeSort(right);
numbers = Merge(left, right);
return;
}
You're still checking the file given by the name ""
. When you put the line
std::ifstream in(file);
it opens the stream to the file specified by the name "" (the value of file
at that point). Later, you say
if (!in)
without actually updating the file used.
Try this:
std::ifstream in; //no file specified
//the following comes before if (!in)
in.open (file);
This will open the stream to the inputted value of file
.
A better way to do this would be to just declare and open the file in place of the second line and lose the first:
std::ifstream in (file); //after they input the filename
Using global variables is a generally bad idea if you don't have any reason to. It's better to pass them around in functions, or contain it all in a class.
Also, I notice you've declared using namespace std;
, but still use std::vector
etc. I would definitely opt for the latter and remove the former. Take care to add the resolution to the couple of things there missing it then though.