C++ Filling 2 arrays

-1

Program needs to collect string "name" and double "speed" from user. User also defines amount of data to input. It must then sort data from fastest to slowest with corresponding "name" listed with its speed. I have successfully managed the program to 'get' user input for amount of data (size of array), and get user input for "name" and "speed" (and test with printing output of exp name[2] and speed[2]).
However, I keep running into a problem where my program will not work, even if I undo changes to when it did work, etc. Sometimes, copying and pasting program into a fresh cpp will solve the problem. I'm sure this code is not the prettiest, but is there something fundamentally wrong that is causing this reoccurring failure, or is it a problem with codeblocks (which has always worked fine)?

int main()
{
    int i,number;
    cout<<"How many do you have? ";
    cin>> number;
    string name[number];
    double speed[number];

cout<<"Enter the names and speeds (name 'space' speed): ";
cout<<endl;

    for (i = 0; i < number; i++)
    {
        cin>>name[number]
        >>speed[number];
    }

    cout<<endl;
    cout<<name[2]<<" "<<speed[2];
    return 0;
}

Note, the time the error happens varies (after entering first int, first entries into array, or not at all and works):

How many do you have? 3

Process returned -1073741571 (0xC00000FD) execution time : 3.663 s Press any key to continue.

c++
arrays
asked on Stack Overflow Oct 29, 2019 by Ian Ray • edited Oct 29, 2019 by Ian Ray

1 Answer

1

I will present 2 solutions one without advanced C++ and the second will make use of the STL and structs.
Solution 1 (The old school way):
Solution without using advance C++ or STL (comments in the code will explain each step):

#include <iostream>

using namespace std;

// utility function to swap two elements
template<typename T>
void swap(T *xp, T *yp)   
{  
    T temp = *xp;  
    *xp = *yp;  
    *yp = temp;  
}  

// we can do better sorting algorithm than this but its the simplest
void bubbleSort(double speeds[], string names[], int n)  
{  
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (speeds[j] < speeds[j+1]){ // if current elements is lower than the next one
                swap(&speeds[j], &speeds[j+1]); // swap speeds 
                swap(&names[j], &names[j+1]); // swap names
            }
        }
    }
}  

int main()
{
    int number;
    cout << "How many do you have? ";
    cin >> number;
    string* names = new string[number];
    double* speeds = new double[number];
    cout << "Enter the names and speeds (name 'space' speed): " << endl;

    for (int i = 0; i < number; i++)
    {
        cin >> names[i] >> speeds[i]; // here its i not number (number is out of range)
                                     // this array goes from 0 to number - 1
    }

    bubbleSort(speeds, names, number); // call sorting algorithm O(n*n)

    cout << "resutls = " << endl;
    for (int i = 0; i < number; i++) // print resutls out
        cout << "Name : " << names[i] << " Speed: " << speeds[i] << endl;

    // free the memory we allocated from the heap (Never forget this)
    delete[] names;
    delete[] speeds;
    return 0;
}

Solution 2 (STL + Structs):
First of all, since the name and speed are coupled together you might need to put them in a
so-called struct which is a package that will put your (name, speed) data together.
There is alternative to this, you might want to use std::pair but since you want your data to be sorted later by ascendant speed we will stick to the struct and define the operator< which will be useful later for sorting.

    // We pack our data inside one struct that contain the name and the speed
    struct NameSpeed
    {
        string name;
        double speed;

        bool operator < (const NameSpeed& other) const // we need to define this operator for sorting
        {
            return (speed < other.speed); // sort based on speed field
        }
    };

Now since we are getting input from user which imply that the size of the array is not defined during compile time we might need to use dynamic memory.
STL (C++ Standard Library) offers std::vector which is array allocated dynamically and have the ability to resize so its really flexible and safer to use than new and delete operators.

Finally here is the code that you need with comments to clarify each step:

#include <iostream>
#include <vector> // we need this for the vector class which is like an array
#include <algorithm> // we need this to sort the array later

using namespace std;

// We pack our data inside one struct that contain the name and the speed
struct NameSpeed
{
    string name;
    double speed;

    bool operator < (const NameSpeed& other) const // we need to define this operator for sorting
    {
        return (speed < other.speed);
    }
};

int main()
{
    int i,number;
    cout<<"How many do you have? ";
    cin>> number;
    vector<NameSpeed> items(number); // resize our array to have number as 
    // size ( better than NameSpeed items[number]; 
    // which is allocated on the stack and we need dynamic memory 
    // and vector manage this for us)

    cout<<"Enter the names and speeds (name 'space' speed): ";
    cout<<endl;
    // Please note that vector class have the operator[] 
    // which allow us to use it just like a normal array
    for (i = 0; i < number; i++) // iterate 
    {
        cin >> items[i].name >> items[i].speed; // get the data from the user name, speed respectively
    }

    cout<<endl;
    sort(items.begin(), items.end()); // sort our array based on speed

    for (const NameSpeed& ns : items) // Iterate through our array
         cout << "Name :" << ns.name << "Speed :" << ns.speed << endl; // print name speed respectively
    return 0;
}
answered on Stack Overflow Oct 29, 2019 by Omarito • edited Oct 29, 2019 by Omarito

User contributions licensed under CC BY-SA 3.0