0

I've declared a function sort that should sort my arrays of strings and numbers, but when I call it, I get an invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string*'.

I also need to get it to keep the array numoftoys in sync with this one as it sorts.

#include <iostream>     //Basic input/output
#include <iomanip>      //Manipulators
#include <string>       //String stuff 
#include <fstream>      //File input/output

using namespace std;

void instruct ();     //Function Declaration for printing instructions 
void input (ifstream &infile, string &names, int &numoftoys);    //Function declaration for getting data from file
void sort (string &names, int &numoftoys, int i);
void rating (string names, int numoftoys, string &raiting);
void headers ();     //Prints headers

int main()
{

  string names [50];       //Array for storing names
  int numoftoys [50];      //Array for storing the number of toys made
  string raiting [50];     //Array for raiting
  int i = 0;
  int p = 0;

  ifstream infile("elves.dat"); //Opens input file "elves.dat"

  instruct();     //Function call to print instructions

  while ((infile >> names[i]) && (infile >> numoftoys[i]))
    {

      ++i;
    }

  sort (names, numoftoys, i);

  for (int p = 0; p<i; p++)
    {
      cout << names[p] << " " << numoftoys[p] << " " << raiting[p] << "\n";
    }



  return 0;
}




/***************************************************/
/* Name: instruct                                  */
/* Description: Prints instructions to user        */
/* Parameters: N/A                                 */
/* Return Value: N/A                               */
/***************************************************/

void instruct ()                                   
{
  cout << "\n" << "This program will calculate the toys made by santas elfs and assign" << "\n";
  cout << "a rating to each elf. It will also sort them and print average, min and max." << "\n";
  cout << "\n" << "Make sure you have a file named elves.dat in the same directory as";
  cout << " this porgram or you will recieve errors.";
  cout << "\n" << "\n";

  return;
}


/***************************************************/
/* Name: input                                     */
/* Description: Reads from file                    */
/* Parameters: N/A                                 */
/* Return Value: N/A                               */
/***************************************************/

void input (ifstream &infile, string &names, int &numoftoys)
{
  infile >> names;
  infile >> numoftoys;


  return;
}


/***************************************************/
/* Name: sort                                      */
/* Description: Sorts Data                         */
/* Parameters: N/A                                 */
/* Return Value: N/A                               */
/***************************************************/
void sort (string &names, int &numoftoys, int i)
{
  bool swapped = true;
  int j = 0;
  int tmp;
  int t = 0;
  while (swapped) {
    swapped = false;
    j++;
    for (int t = 0; t<i-j; t++);{
    if (names[t] > names[t + 1]){
      tmp = names[t];
      names[t] = names[t + 1];
      names[t+1] = tmp;
      swapped = true;
    }
      }
  }
}
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Bob Smith
  • 1
  • 1
  • This would be much easier if you created an array (or vector) of structs containing the toy names and number of toys and just sorted that. – Duck Dec 08 '11 at 17:19
  • i wasnt taught that till just today and the prgram was due yesterday so there has to be another way. Il look into that though – Bob Smith Dec 08 '11 at 17:20
  • 2
    The second part of this question is a possible duplicate of [How do I sort two parallel arrays?](http://stackoverflow.com/questions/8434272/how-do-i-sort-two-parallel-arrays) – Rob Kennedy Dec 08 '11 at 17:42
  • 1
    Gee. This assignment looks oddly similar to [the one from Sam LaManna](http://stackoverflow.com/questions/8434272/how-do-i-sort-two-parallel-arrays). You don't happen to know him, do you? – Rob Kennedy Dec 08 '11 at 17:42

3 Answers3

2

You are trying to pass an array of 50 strings to sort, which takes a reference to a single string.

Try declaring sort as any one of these:

void sort( string names[50], int numoftoys[50], int i)
void sort( string names[], int numoftoys[], int i)
void sort( string* names, int* numoftoys, int i)

If you do any of those, you won't have to change your function call at all:

sort (names, numoftoys, i);

But, really, just stop using raw arrays and pointers the moment you discover std::vector<> in your studies.


EDIT: 2nd bug.

For some reason, you have this code:

int tmp;
 ...
tmp = names[t];

You have declared tmp to be one type (int), but have used it as if it were a different type (string). It doesn't make sense to say "Assign a copy of this string inside that int.

You should declare tmp to have the appropriate type for its use.

P.s. Once you learn about std::swap(), you can dispose of the tmp variable altogether.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Thanks, that helped but i now get an error: cannot convert 'std::basic_string, std::allocator >' to 'int' in assignment – Bob Smith Dec 08 '11 at 17:29
  • @Bob: In the sort function, tmp is of the wrong type. It's type `int`, and it should be `string`. Will your teacher allow you to use [`std::swap`](http://en.cppreference.com/w/cpp/algorithm/swap)? – Benjamin Lindley Dec 08 '11 at 17:33
0

You're passing an array of string (a string *) to a function expecting a string reference. Either make the reference to name constant (which you can't do as you are modifying the original, or pass it as a pointer.

Or use a better container than a straight array.

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
0

I do not understand the exercise, but because the name and the number are linked together, your data structure should reflect this. It would be easiest to just use std::pair.

#include<string>
#include<list>
#include<utility>

int main()
{
  typedef std::pair<std::string, int> name_and_number_t;
  std::list<name_and_number_t> names_and_numbers;

  //...
  name_and_number_t name_and_number;
  while ((infile >> name_and_number.first) && (infile >> name_and_number.second))
  {
    names_and_numbers.push_back(name_and_number);
  }
  names_and_numbers.sort();
  //...
}

I do not know enough about the rating thing. Maybe I'd go for

// maybe this
struct number_and_rating; 
// or that
typedef std::pair<int, string> number_and_rating;
// for
typedef std::map<std::string, number_and_rating> toy_container_t;
Chris Frederick
  • 5,482
  • 3
  • 36
  • 44
Herb
  • 76
  • 1
  • 4