-4

Having trouble storing strings into an array. I tried a multi-dimensional char array but it didn't work. I would ideally like a multi-dimensional string array but every time I try I get the error

cannot convert std::string (*)[100] {aka std::basic_string<char> (*)[100]} to std::string*

Don't even understand what that means. I tried printing the array in my function input_new_student which is where I store the string just to test it, and no luck. The same thing is happening to all my arrays. I've looked it up but I feel like im overlooking something very simple, please help.

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>

void print_menu();
int get_selection();
std::string get_Name();
float get_GPA();
int get_Year();
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[]);
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[]);
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size);
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum);

using namespace std;

int main()
{
    std::string student_names[100];
    float student_GPA[100];
    int student_start_year[100];
    int ramapo_id[100];
    int userChoice;
    int index = 0;
    int size = 0;
    float sum = 0.0;

    do
    {
        print_menu();
        userChoice = get_selection();
        if (userChoice == 1)
        {
            input_new_student(student_names, student_GPA, student_start_year, index, ramapo_id);
            index++;
        }
        if (userChoice == 2)
        {
            print_all(student_names, student_GPA, student_start_year, index, size, ramapo_id);
        }
        if (userChoice == 3)
        {
            print_by_year(student_names, student_GPA, student_start_year, index, size);
        }
        if (userChoice == 4)
        {
            print_statistics(student_names, student_GPA, student_start_year, index, size, sum);
        }
        if (userChoice == 5)
        {
            return 0;
        }
    } while(userChoice > 0 && userChoice < 4);
    return 0;
}
void print_menu()
{
    cout << "Please pick from the following menu " << endl;
    cout << "1. Add a new student " << endl;
    cout << "2. Print all students " << endl;
    cout << "3. Print students by year " << endl;
    cout << "4. Print student statistics " << endl;
    cout << "5. Quit" << endl;
}
int get_selection()
{
    int userChoice;
    cin >> userChoice;
    while (userChoice > 4 || userChoice < 1)
    {
        cout << "Error: Invalid input, please try again: ";
        cin >> userChoice;
    }
    return userChoice;
}
string get_Name()
{
    std::string student_name;

    cout << "Please enter the student's name: ";
    cin >> student_name;

    return student_name;
}
float get_GPA()
{
    float student_GPA;

    cout << "Please enter the GPA: ";
    cin >> student_GPA;

    return student_GPA;
}
int get_Year()
{
    int student_year;

    cout << "Please enter the start Year: ";
    cin >> student_year;

    return student_year;
}
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[])
{
    //information generation
    srand((unsigned)time(0));
  int random_integer = rand();
    ramapo_id[index] = random_integer;

    //information acquisition
    student_names[index] = get_Name();
    student_GPA[index] = get_GPA();
    student_start_year[index] = get_Year();
}
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[])
{
    for (int i = 0; i < size; i++) {
    cout << student_names[i] << " - " << ramapo_id[i] << endl;
    }
}
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size)
{
    int student_year_identifier;
    cout << "Which year would you like to display?: ";
    cin >> student_year_identifier;
    for (int i = 0; i < size; i++)
    {
        if (student_year_identifier == student_start_year[i])
        {
            cout << "There were " << index << "students in that year" << endl;
        }
        else {
            cout << "There were no students in that year" << endl;
        }
    }
}
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum)
{
    cout << "Total: " << index << endl;

    float avg = 0.0;
  for (int i = 0; i < size; ++i)
  {
      sum += student_GPA[i];
  }
  avg = ((float)sum)/size;
    cout << "GPA: " << avg << endl;
}
Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
gf807
  • 81
  • 1
  • 2
  • 7
  • 3
    You should avoid calling `srand` more than once. [Link](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once). – François Andrieux Jul 11 '17 at 19:53
  • Consider creating a class to wrap all these data, use vectors (maybe tuples in your case) in place of c-style arrays and a debugger to step through your code. – Papipone Jul 11 '17 at 19:58
  • 1
    The compiler shows the line where the error occurred. Why do you think you can skip that? –  Jul 11 '17 at 19:59
  • [Cannot reproduce](http://coliru.stacked-crooked.com/a/07d858dae897973f). (I did have to fix your input validation to let me quit properly though, and you never increment size, so print_all does nothing). – Miles Budnek Jul 11 '17 at 19:59
  • Ok. I edited it to simply {rand();} and set it equal to int random integer. – gf807 Jul 11 '17 at 20:00
  • Get `srand((unsigned)time(0));` out of `input_new_student`. It should be in `main()` and it should be called 1 time before your functions execute. Not every time you need a new random number. This has nothing to do with the error message however. You did not mention which line that the error occurs on and I did not spot it in the ~2 minutes I spent looking at all your code. – drescherjm Jul 11 '17 at 20:02
  • @drescherjm that error occurs in the declerations when I make the array multi-dimensional. For example `void input_new_student(std::string student_names[][], float student_GPA[], int student_start_year[], int index, int ramapo_id[]);` – gf807 Jul 11 '17 at 20:17
  • @drescherjm i guess my main concern is with the functions `input_new_student` and `print_all`. Am I not storing the string correctly into the array? Why would it not print? Am I incrementing correctly(in past projects this was correct)? – gf807 Jul 11 '17 at 20:20
  • You look to be storing the data correctly. Once you get past the compiler error you should use your debugger to verify that. Execute line by line and look at your variables. – drescherjm Jul 11 '17 at 20:20
  • `std::string student_names[][]` is the problem. Why do you have 2 []s? I don't see that in the code you show. – drescherjm Jul 11 '17 at 20:21
  • @MilesBudnek mentioned why your print_all was not printing anything. – drescherjm Jul 11 '17 at 20:30
  • instead of passing these raw arrays, you should learn to use `std::vector` or `std::array` and pass them by `const reference` or `reference` as per your need. – aniliitb10 Jul 11 '17 at 20:45
  • @aniliitb10 I personally would have liked to use a vector in this instance, but the project specifically said to use arrays – gf807 Jul 11 '17 at 20:54
  • 1
    Then just clean your code, print helpful messages, debug (like if you input 5, it won't quit, instead, it will ask to enter again); you will be able to get it working. – aniliitb10 Jul 11 '17 at 21:09

3 Answers3

1

I recommend you have a container of structures rather than multiple containers:

struct Student_Info
{
  std::string  name;
  double       gpa;
  unsigned int starting_year;
}

typedef std::vector<Student_Info> Student_Info_Container;
Student_Info_Container database;

// You could also have an array of student information:
static const size_t MAXIMUM_STUDENTS = 32U;
Student_Info_Container student_information[MAXIMUM_STUDENTS];

Placing the information into a structure support encapsulation and makes the program more efficient.

With parallel arrays, there is a possibility of synchronization issues. For example, the GPA for student 3 may be at index 4 of the array.

If you are restricted to arrays, you would only need to pass 2 parameters to your functions, the array and the capacity of the array.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Due to the project requirements I cannot use a struct. But this is a very useful answer. Thank you. – gf807 Jul 11 '17 at 22:27
  • @gf807 That's quite usual. The only advice I can give is: Leave that course. The professor is incompetent to teach you the right road to go. – user0042 Jul 11 '17 at 22:42
  • @user0042 well he's the only one that teaches it now and it is only a CS2 class, and its the first project which is a refresher on CS1 topics. So hopefully we get into the nitty gritty. I want to make pong and you need to use structs for it lol. – gf807 Jul 11 '17 at 23:16
0

There are few issues with your code, e.g.:

  1. Your code is difficult to debug because you are using infinite while loops while taking input (e.g. in main and get_selection function).
  2. How would you know if your code is working? At least, print something which indicates that your code is working, like cout << "Student added suuccessfully"; in input_new_student function.

I made these above mentioned changes and you can see that (at least) your code is working for option 1 at http://ideone.com/D5x8Eh

PS: I didn't get that compilation error, you should mention the compiler and flags you are using.

aniliitb10
  • 1,259
  • 10
  • 14
0

So as an update, the reason I wasn't able to print my array was begin I was not incrementing in my for loop. Thanks to @milesbudnek , @dreschjerm. I was able to see that my code was actually printing by adding the messages, this was prior to the suggestions, but thanks for the suggestion. Here is the code as it is now. Currently I just need to find a way to find values in the array (which I will search for) and create the multi-dimensional array for the strings.

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>

void print_menu();
int get_selection();
std::string get_Name();
float get_GPA();
int get_Year();
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[]);
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[]);
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size);
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum);

using namespace std;

int main()
{
    std::string student_names[100];
    float student_GPA[100];
    int student_start_year[100];
    int ramapo_id[100];
    int userChoice;
    int index = 0;
    int size = 0;
    float sum = 0.0;

    //seed
    srand((unsigned)time(0));

    do
    {
        print_menu();
        userChoice = get_selection();
        if (userChoice == 1)
        {
            input_new_student(student_names, student_GPA, student_start_year, index, ramapo_id);
            index++;
            size++;
        }
        if (userChoice == 2)
        {
            print_all(student_names, student_GPA, student_start_year, index, size, ramapo_id);
        }
        if (userChoice == 3)
        {
            print_by_year(student_names, student_GPA, student_start_year, index, size);
        }
        if (userChoice == 4)
        {
            print_statistics(student_names, student_GPA, student_start_year, index, size, sum);
        }
        if (userChoice == 5)
        {
            return 0;
        }
    } while(userChoice > 0 && userChoice < 5);
    return 0;
}
void print_menu()
{
    cout << "Please pick from the following menu " << endl;
    cout << "1. Add a new student " << endl;
    cout << "2. Print all students " << endl;
    cout << "3. Print students by year " << endl;
    cout << "4. Print student statistics " << endl;
    cout << "5. Quit" << endl;
}
int get_selection()
{
    int userChoice;
    cin >> userChoice;
    while (userChoice > 5 || userChoice < 1)
    {
        cout << "Error: Invalid input, please try again: ";
        cin >> userChoice;
    }
    return userChoice;
}
string get_Name()
{
    std::string student_name;

    cout << "Please enter the student's name: ";
    cin >> student_name;

    return student_name;
}
float get_GPA()
{
    float student_GPA;
    do {
        cout << "Please enter the GPA: ";
        cin >> student_GPA;
    } while(!(student_GPA < 4.0 && student_GPA > 0.0));


    return student_GPA;
}
int get_Year()
{
    int student_year;

    do {
        cout << "Please enter the start Year: ";
        cin >> student_year;
    } while(!(student_year > 1972 && student_year < 2015));

    return student_year;
}
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[])
{
    //information generation
  int random_integer = rand()%900000 + 100000;
    ramapo_id[index] = random_integer;

    //information acquisition
    student_names[index] = get_Name();
    student_GPA[index] = get_GPA();
    student_start_year[index] = get_Year();

    //Notification
    cout << endl;
    cout << "The student with R# " << random_integer << " was created." << endl;
    cout << endl;
}
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[])
{
    cout << endl;
    for (int i = 0; i < size; i++) {
    cout << student_names[i] << " - " << ramapo_id[i] << endl;
    }
    cout << endl;
}
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size)
{
    int student_year_identifier;
    //to trigger the response that there ARE students in that year
    bool trigger;
    int student_count = 0;
    cout << "Which year would you like to display?: ";
    cin >> student_year_identifier;
    for (int i = 0; i < size; i++)
    {
        if (student_start_year[i] == student_year_identifier)
        {
            bool trigger = true;
            student_count++;
        }
    }
    if (trigger = true) {
        cout << endl;
        cout << "There are " << student_count << " student(s) in that year" << endl;
        cout << endl;
    }
    else {
        cout << endl;
        cout << "There are no students in that year." << endl;
        cout << endl;
    }
}
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum)
{
    //Print Total
    cout << "Total: " << index << endl;

    //Print GPA average
    int smart_kids = 0;
    float avg = 0.0;
  for (int i = 0; i < size; ++i)
  {
      sum += student_GPA[i];
  }
  avg = ((float)sum)/size;
    cout << "GPA: " << std::setprecision(3) << avg << endl;

        //Print # of students above 2.0
        for (int i = 0; i < size; i++)
        {
            if (student_GPA[i] > 2.0)
            {
                smart_kids++;
            }
        }
        cout << "Above a 2.0: " << smart_kids << endl;
}
gf807
  • 81
  • 1
  • 2
  • 7
  • `while (userChoice > 4 || userChoice < 1)` still has a bug. You can't enter 5. – drescherjm Jul 11 '17 at 23:27
  • @drescherjm I fixed that. Took care of all my errors, just need a way to fit first and last name in the string. Not sure if this can be done using a sole string array, or if you need a multi-dimensional one. The name has to be taken in the **get_name** function – gf807 Jul 11 '17 at 23:38
  • The problem is the way you input the name. `cin >> student_name;` remember that cin will only read up to the first space. https://stackoverflow.com/questions/5838711/stdcin-input-with-spaces – drescherjm Jul 11 '17 at 23:41
  • once my compiler starts working again, i'll test `getline(cin,name)` – gf807 Jul 11 '17 at 23:46
  • @drescherjm ok so it works but it only prints the last name now. – gf807 Jul 11 '17 at 23:52