0

I am working on a C++ program, but I discovered that a function for sorting through arrayed struct members transferred from a text file didn't execute and ended up displaying the unsorted struct members.

This program is intended for my university course's semester project, where I made a basic ride-sharing program based on C++. The program must read the text file containing driver information and transfer it to arrayed structs, where it will then begin sorting from the lowest to highest price and display the sorted struct members. I did some research on a C++ textbook and even went on the a few forums to find similar problems, but I kept getting the same results as the text file was originally.

Here is the content of the text file for reference.

Annie Aliston
0174987723
Range Rover Evoque
60
6.00

Riley Winston
0174965739
Ford Everest
70
2.50

Here is my coding

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string.h>

using namespace std;

struct ProSort
{
    char nameProvider[10][40]; //40 character limit for nameProvider
    char numPhoneProvider[10][11]; //11 character limit for numPhoneProvider
    char nameVehicle[10][40]; //40 character limit for nameVehicle
    double KMh[10];
    double price[10];
};

ProSort sortingS[7]; //7 set of structs, but I'll put one of the said struct in the sorting function as an example below.

void sortS(ProSort, int);

void share_ride_sort_input(ProSort sortingS[], fstream& File)
{
    File.open("sList/s4-Wheels.txt", ios::in);
    {
        if (File.is_open())
        {
            int a = 0;
            while (!File.eof())
            {
                File >> ws;
                File.getline(sortingS[0].nameProvider[a], 40);
                File >> ws;
                File.getline(sortingS[0].numPhoneProvider[a], 11);
                File >> ws;
                File.getline(sortingS[0].nameVehicle[a], 40);
                File >> sortingS[0].KMh[a];
                File >> sortingS[0].price[a];

                //Contents of the text file will be assigned to the struct members above

                a++; //Array index number will increase until the end of the text file
            }
        }
    }
    File.close();
}

void sortS(ProSort sortingS, int SIZE) //The sorting function for said issue above
{
    int index;
    int smallestIndex;
    int location;
    char temp[100];
    double temp2;

    for (index = 0; index < SIZE - 1; index++)
    {
        smallestIndex = index;

        for (location = index + 1; location < SIZE; location++)
        {
            if (sortingS.price[index] > sortingS.price[smallestIndex]) 
            {
                smallestIndex = location;

                strcpy(temp, sortingS.nameProvider[smallestIndex]);
                strcpy(sortingS.nameProvider[smallestIndex], sortingS.nameProvider[index]);
                strcpy(sortingS.nameProvider[index], temp);

                strcpy(temp, sortingS.numPhoneProvider[smallestIndex]);
                strcpy(sortingS.numPhoneProvider[smallestIndex], sortingS.numPhoneProvider[index]);
                strcpy(sortingS.numPhoneProvider[index], temp);

                strcpy(temp, sortingS.nameVehicle[smallestIndex]);
                strcpy(sortingS.nameVehicle[smallestIndex], sortingS.nameVehicle[index]);
                strcpy(sortingS.nameVehicle[index], temp);

                temp2=sortingS.KMh[smallestIndex];
                sortingS.KMh[smallestIndex]=sortingS.KMh[index];
                sortingS.KMh[index]=temp2;

                temp2=sortingS.price[smallestIndex];
                sortingS.price[smallestIndex]=sortingS.price[index];
                sortingS.price[index]=temp2;

            // Basically all of the arrayed struct members with the same array index will move together as one whole set of driver info until every set of struct members is sorted
            }
        }
    }
}

void share_ride_output(ProSort sortingS[], fstream& File) //Function for displaying the sorted struct members by writing to a text file.
{
    File.open("sList/s4-Wheels-sorted.txt", ios::out);
    {
        if (File.is_open())
        {
            for(int i=0; i<2; i++)
            {
                File<<sortingS[0].nameProvider[i]<<endl;
                File<<sortingS[0].numPhoneProvider[i]<<endl;
                File<<sortingS[0].nameVehicle[i]<<endl;
                File<<sortingS[0].KMh[i]<<" km/h"<<endl;
                File<<"£"<<sortingS[0].charge[i]<<endl;
                File<<"\n";
            } //This is for writing 2 sets of struct members that was assigned in the share_ride_sort_input function to another text file.
        }
    }
    File.close();
}

int main()
{
    fstream File;
    const int SIZE = 7;

    share_ride_sort_input(sortingS, File);

    for(int i=0; i<7; i++) //Originally this was meant for 7 car classes, but only the struct members from the s4-wheels.txt file will be put as an example
    {
        sortS(sortingS[i], SIZE);
    }

    share_ride_output(sortingS, File); //Sorted struct members will be written to a text file.

    return 0;
}

I expect the output to the text file to be:

Riley Winston
0174965739
Ford Everest
70
2.50

Annie Aliston
0174987723
Range Rover Evoque
60
6.00

But instead, I got the output to be unsorted like this:

Annie Aliston
0174987723
Range Rover Evoque
60
6.00

Riley Winston
0174965739
Ford Everest
70
2.50

No error message is displayed, as the program runs without any warnings from the compiler. I would assume that I did something wrong in the sorting formula, but I couldn't seem to get other solutions to work either.

  • 2
    It's good that you use structures, but you kind of using it in the wrong way. Instead of keeping a single structure containing arrays, have an array of structures. Each structure object should correspond to a single record in the file. – Some programmer dude Jun 14 '19 at 10:34
  • 1
    I also recommend that you read [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Some programmer dude Jun 14 '19 at 10:35
  • 1
    Lastly, and what might be your issue, when you call `sortS` you pass the structure *by value*. Passing by value means that you create an independent *copy* of the "value" (structure in your case). Modifying the copy will of course not modify the original. – Some programmer dude Jun 14 '19 at 10:36
  • There is something fishy with your sorting function. Your inner loop ranges over `location` but you still use `index` to access elements. Also, the logic is reversed. Assume a sorted list, so prices[0] = 2.5 and prices[1] = 6. On the first iteration, smallestIndex = 0 and location = 1. Your condition `prices[1] > prices[0]` is true, so you swap! – Botje Jun 14 '19 at 10:42
  • I wonder when people learn don't write C like code in C++? It so problematic. https://youtu.be/YnWhqhNdYyk – Marek R Jun 14 '19 at 10:42

1 Answers1

0

Main problem with your code is that actually it is not a C++. It is mostly C which is much harder to handle.

Second problem as someone has point out in comment, you reversed task hint. Instead doing array of structs you created an arrays inside a struct, which in this case made things even harder.

When you write C++ code, don't use C features like: char[] for strings (use std::string), C arrays SomeType variable[number] (use std::vector or std::array).

Start with something like that and the use std::sort and it will turn out quite easy:

struct Ride {
    std::string dirver;
    std::string phone;
    std::string vehicle;
    double distance;
    double price;
};


std::istream& loadRide(std::istream& input, Ride& ride)
{
    input >> std::ws; // consume white spaces in front
    std::getline(input, ride.dirver);
    std::getline(input, ride.phone);
    std::getline(input, ride.vehicle);
    return input >> ride.distance >> price; 
}

std::istream& loadRides(std::istream& input, std::vector<Ride>& rides)
{
    rides.clear();
    Ride ride;
    while(loadRide(input, ride)) {
        rides.push_back(ride);
    }
}

std::vector<Ride> loadRidesFromFile(const std::string& fileName)
{
    std::ifstream f{ fileName };
    std::vector<Ride> rides;
    loadRides(f, rides);
    return rides;
}
Marek R
  • 23,155
  • 5
  • 37
  • 107