0

I need to write a program that reads an unknown number of numerical data from a text file into an array and then uses a sorting parameter to sort the numbers. I've been trying for hours and I can't get the program to work

void sort(double &, double arr[], int s);

int main()
{
    fstream myfile;
    int size, i = 0;
    const int n = 1000;
    double x[n];

    //reading data
    myfile.open("data.txt");
    if (myfile.fail())
    {
        cout << "Error Opening File" << endl;
        exit(1);
    }
    while (!myfile.eof())
    {
        myfile >> x[i];
        cout << x[i] << endl;
        i++;
    }
    size = i - 1;
    cout << size << " number of values in file" << endl;
    myfile.close();

    i = 0;
    while (size > i)
    {
        cout << x[i] << endl;
        i++;
    }
    //sorting
    sort(x[n], x[n], size);
    i = 0;
    while (size > i)
    {
        cout << x[i] << endl;
        i++;
    }
    return 0;
}

void sort(double &, double arr[], int s)
{
    bool swapped = true;
    int j = 0;
    int tmp;
    while (swapped) 
    {
        swapped = false;
        j++;
        for (int i = 0; i < s - j; i++) 
        {
            if (arr[i] > arr[i + 1])
            {
                tmp = arr[i];
                arr[i] = arr[i + 1];
                &[i + 1] = &tmp;
                swapped = true;
            }
        }
    }
}
  • Welcome to StackOverflow! I'd recommend adding a tag to your answer for your programming language to attract answers from experts in that specific area. – Phil Tune Dec 01 '14 at 22:50
  • @philtune I just did that for him. Also Stephan, what is the current problem with the code? – Emz Dec 01 '14 at 22:51
  • I'm going to suggest `&[i + 1] = &tmp` isn't going to do much of anything good. `std::swap` would be better than that trio of common code, and honestly `std::sort` would likewise be better than that bubble sort. And this: `while (!myfile.eof())` [**is wrong.**](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – WhozCraig Dec 01 '14 at 22:54
  • _@Stephan_Koellner_ Did you consider using [`std::sort()`](http://en.cppreference.com/w/cpp/algorithm/sort)? – πάντα ῥεῖ Dec 01 '14 at 23:00
  • I have an error about converting from double to double and expecting a "{" in front of a lamdba body – Stephan Koellner Dec 01 '14 at 23:06
  • Again, `&[i + 1] = &tmp;` makes no sense. That line should be `x[i+1] = tmp;` And `tmp` should be `double`, not `int`. – WhozCraig Dec 01 '14 at 23:10
  • I need to have the sorting function as a parameter – Stephan Koellner Dec 01 '14 at 23:11
  • Great. Describing what you *mean* by that in your question may save it from going on-hold. The first parameter to your sort function isn't even named. – WhozCraig Dec 01 '14 at 23:13

2 Answers2

1
while (!myfile.eof()) 

is almost ALWAYS wrong, Why is iostream::eof inside a loop condition considered wrong? as you end up reading the end of file. Use instead

while (myfile >> x[i])

In your case, you can just declare x as a std::vector, like

std::vector<double> x;

read the content into the vector, then use

std::sort(x.begin(), x.end());

Nothing more simple.

And for a complete C++ standard library solution, you can use iterators and sorting algorithms, like

#include <algorithm>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>

int main()
{ 
    std::fstream myfile("data.txt"); // should also test if it's open correctly
    std::vector<double> x(std::istream_iterator<double>(myfile), {});
    std::sort(x.begin(), x.end());

    for(const auto& elem: x)
        std::cout << elem << " ";
}

You can easily map the code above to a function. I have no idea what you mean by a sorting parameter. If you need to be able to sort ascending/descending, you may use std::less or std::greater (need to #include <functional>), as a third parameter for std::sort, like

std::sort(x.begin(), x.end(), std::greater<double>()); // sorts in descending order

or write your own comparator functor/lambda function.

Community
  • 1
  • 1
vsoftco
  • 52,188
  • 7
  • 109
  • 221
  • I changed my code to this – Stephan Koellner Dec 01 '14 at 23:20
  • fstream myfile; int size, i = 0; const int n = 1000; std::vector x; //reading data myfile.open("data.txt"); if (myfile.fail()){ cout << "Error Opening File" << endl; exit(1); } while (!myfile.eof()) { myfile >> x[i]; cout << x[i] << endl; i++; } size = i - 1; cout << size << " number of values in file" << endl; myfile.close(); i = 0; while (size > i) { cout << x[i] << endl; i++; } //sorting std::sort(x.begin(), x.end()); i = 0; while (size > i) { cout << x[i] << endl; i++; } return 0; – Stephan Koellner Dec 01 '14 at 23:21
  • You know you can initialize that vector with the istream iterators `std::vector x((std::istream_iterator(myfile)), std::istream_iterator());` and skip the copy-step. – WhozCraig Dec 01 '14 at 23:21
  • @WhozCraig yes I know, as they are iterators, but I felt it's just too much :) Although I guess it looks actually simpler, will update, thanks. – vsoftco Dec 01 '14 at 23:21
  • @StephanKoellner It's really hard to read your code in the comment. The `while(!myfile.eof())` is wrong, use what I pointed out above. Then test the code and see if it works! You also need to use the `push_back` function for `std::vector`. First, do `while(myfile >> tmp){ x.push_back(tmp); ....}`, where `tmp` is some temporary `double` declared before. – vsoftco Dec 01 '14 at 23:35
0

My C++ is rusty and I am without a compiler, I will update this if any errors are encountered.

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

static bool sort_function (double p, double q);

int main()
{
    fstream myfile;

    // opening file
    myfile.open("data.txt");
    if (myfile.fail())
    {
        cout << "Error Opening File" << endl;
        exit(1);
    }

    // reading data and storing data
    vector<double> x;
    double tmp;
    while (myfile >> tmp)
    {
        x.push_back(tmp);
    }
    myfile.close();
    cout << x.size() << " number of values in file" << endl;

    // unsorted print data from vector
    for (vector<double>::iterator it = x.begin(); it != x.end(); ++i)
    {
        cout << *it << endl;
    }

    // sorted print data from vector
    sort(x.begin(), x.end(), sort_function);
    for (vector<double>::iterator it = x.begin(); it != x.end(); ++i)
    {
        cout << *it << endl;
    }

    return 0;
}

static bool sort_function (double p, double q)
{
    return p > q;
}

There are some differences to your code.

  • It uses std::vector instead of an array. It is dynamic and has some pleasant functionality like dynamic length, a size counter and sorting.
  • I split it into four blocks of code, opening, storing, unsorted and sorting.

So what it does

  1. As it were before, it tries to load data.txt, if it fails it exists.
  2. It reads data, storing it in our temp variable tmp to then push it into our vector x. It then proceeds to close the file and print the number of values x.size().
  3. It prints the unsorted vector, as it were in your code.
  4. It finally utilizes std::sort(begin, end, function) to sort the vector.
Emz
  • 1,280
  • 1
  • 14
  • 26