C++ error: invalid initialization of non-const reference of type char&

I started studying c++ and in the process of studying arrays of strings I encountered several errors that I can't understand on my own. Here is the full code:

#include <iostream>  // std::cout
#include <cstdio>    // gets
#include <cstring>   // strcmp
using namespace std;

/* func declarations */
int main();
void displayMenu();
void displayWorkers(char&, int); // &workers - означает, что необходимо рассматривать аргумент как указатель (внутри функции * не используется)

/* variables declarations */
char workers[][2][30] = {
    "Alex", "22-33-44", "24300",
    "Ivan", "55-33-66", "30000",
    "Pavel", "22-33-44", "24300",
    "Антон", "", "25000",
    "Жора", "44-33-11", "25000"
};
char projects[][2] = {};

/* functions */

int main() {
    char listen[120];
    // show menu
    do {
        displayMenu();
        fflush (stdout);
        scanf("%119s", listen);
        if (strcmp(listen, "1") == 0) {
            displayWorkers(&workers, 5);
        } else if (strcmp(listen, "2") == 0) {
            cout << " -- Projects --\n";
        }
    } while (strcmp(listen, "quit") != 0);
    return 0;
}

/**
 * Display menu
 */
void displayMenu() {
    cout << " == Menu ==\n";
    cout << " 1 - Показать всех работников\n";
    cout << " 2 - Показать все проекты\n";
    cout << " quit - Выход\n";
}

/**
 * displayWorkers
 * @param workers
 * @param count
 */
void displayWorkers(char &workers, int count) {
    int i;
    cout << "Workers\n Name\t\t|Phone\t\t|Salary\n";
    for (i = 0; i < count; i++) {
        cout << workers[i][0] << "\t\t|" << workers[i][1] << "\t\t|" << workers[i][2] << "\n";
    }
}

Here are the errors I get when compiling:

$ g++ study1.cpp -o study
study1.cpp: In function ‘int main()’:
study1.cpp:36:39: error: invalid initialization of non-const reference of type ‘char&’ from an rvalue of type ‘char (*)[8][2][30]’
             displayWorkers(&workers, 5);
                                       ^
study1.cpp:14:6: error: in passing argument 1 of ‘void     displayWorkers(char&, int)’
 void displayWorkers(char&, int); // &workers - означает, что     необходимо рассматривать аргумент как указатель (внутри функции * не     используется)
      ^
study1.cpp: In function ‘void displayWorkers(char&, int)’:
study1.cpp:64:26: error: invalid types ‘char[int]’ for array subscript
         cout << workers[i][0] << "\t\t|" << workers[i][1] << "\t\t|"     << workers[i][2] << "\n";
                          ^
study1.cpp:64:54: error: invalid types ‘char[int]’ for array subscript
         cout << workers[i][0] << "\t\t|" << workers[i][1] << "\t\t|"     << workers[i][2] << "\n";
                                                      ^
study1.cpp:64:82: error: invalid types ‘char[int]’ for array subscript
         cout << workers[i][0] << "\t\t|" << workers[i][1] << "\t\t|"     << workers[i][2] << "\n";

I really hope to indicate specifically my mistakes, and not throw links, as I have already searched long and hard, but to no avail.

 0

3 answers

You are confusing links and pointers. It's not the same thing (at the C++level).

Link:

  • You can't change the reference (you can't refer to another object)
  • A reference should not be dereferenced when accessing the object it refers to

Pointer:

  • You can change the pointer (to point to another object)
  • When accessing the object it points to, it must be dereferenced pointer

So pointers are potentially less secure.

In your case, you define a function that takes as the first argument a reference to char. This means that you can use this link to change the character passed from the outside, no more.

I would advise you to rewrite the program as follows:

  1. Add a class to it that will represent the employee.
  2. Remove global variables.
  3. Replace warm lamp-like (but very uncomfortable) character arrays on std::string.
  4. Use the std::vector wrapper to represent dynamic arrays.
 1
Author: awesoon, 2015-06-07 05:31:48

For starters, if you're already writing in C++, use idiomatic containers. No char[][][][], of which some parentheses indicate that it is a string, and others indicate that it is an array.

Then, the three elements "Alex", "22-33-44", "24300" are not just three strings of some kind, they are things with different semantics, and are obviously combined into one structure.

Then, in your code, you define here and there some magic constants: 30, 120, etc. I hope you understand, what it threatens. If not, think for yourself.

Now for a specific error. According to your code, the displayWorkers procedure requires the first argument to be char& - that is, a reference (not a pointer) to char (that is, a single character). You both pass and use the workers structure inside.

Your code should look something like this:

#include <iostream>
#include <vector>

using namespace std;

/* types */
struct worker {
    string name;
    string phone;
    unsigned salary;
};

/* func declarations */
void displayMenu();
void displayWorkers(const vector<worker>&);

/* global variables */
vector<worker> workers = {
    { "Alex", "22-33-44", 24300 },
    { "Ivan", "55-33-66", 30000 },
    { "Pavel", "22-33-44", 24300 },
    { "Антон", "", 25000 },
    { "Жора", "44-33-11", 25000 }
};

/* functions */

int main() {
    string listen;
    // show menu
    do {
        displayMenu();
        getline(cin, listen);
        if (listen == "1") 
            displayWorkers(workers);
        } else if (listen == "2") {
            cout << " -- Projects --\n";
        }
    } while (listen != "quit");
    return 0;
}

/**
 * Display menu
 */
void displayMenu() {
    cout << " == Menu ==\n";
    cout << " 1 - Показать всех работников\n";
    cout << " 2 - Показать все проекты\n";
    cout << " quit - Выход\n";
}

/**
 * displayWorkers
 * @param workers
 */
void displayWorkers(const vector<worker>&workers) {
    cout << "Workers\n Name\t\t|Phone\t\t|Salary\n";
    for (auto& w : workers) {
        cout << w.name << "\t\t|" << w.phone << "\t\t|" << w.salary << "\n";
    }
}

Verification: http://ideone.com/YOdMsy

 0
Author: VladD, 2015-06-07 05:38:07

This is

char workers[][2][30] = {
    "Alex", "22-33-44", "24300",
    "Ivan", "55-33-66", "30000",
    "Pavel", "22-33-44", "24300",
    "Антон", "", "25000",
    "Жора", "44-33-11", "25000"
};

Defines a 3-dimensional array of type char, which you are trying to fill in the style of a one-dimensional array of type const char*. Judging by the data you use, you need a structure and a one-dimensional array. If it's C++, then you can do it, for example, like this: The structure itself:

struct Employee
{
    std::string m_Name;
    std::string m_Number;
    std::string m_AnotherNumber;

    Employee(const std::string& name, const std::string& number, 
        const std::string& anotherNumber) : 
        m_Name(name),
        m_Number(number),
        m_AnotherNumber(anotherNumber)
    {

    }
};

Using:

Employee workers[] = {
    Employee("Alex", "22-33-44", "24300"),
    Employee("Ivan", "55-33-66", "30000"),
    Employee("Pavel", "22-33-44", "24300"),
    Employee("Антон", "", "25000"),
    Employee("Жора", "44-33-11", "25000")
};

std::cout << workers[2].m_Name << "\n";

DisplayWorkers, respectively, will look like this:

void displayWorkers(Employee workers[], int count) 
{
    std::cout << "Workers\n Name\t\t|Phone\t\t|Salary\n";
    for(int i = 0; i < count; i++) {
        std::cout << workers[i].m_Name << "\t\t|" << workers[i].m_Number << "\t\t|" 
            << workers[i].m_AnotherNumber << "\n";
    }
}

Well, since C++, then let's add the example to normal C++ decisions:

#include <iostream>
#include <string>
#include <vector>
#include <iomanip>

class Employee
{
public:
    Employee(const std::string& name, const std::string& number, 
        const std::string& anotherNumber) : 
        m_Name(name),
        m_Number(number),
        m_AnotherNumber(anotherNumber)
    {

    }
    std::string name() const
    {
        return m_Name;
    }

    std::string number() const
    {
        return m_Number;
    }

    std::string anotherNumber() const
    {
        return m_AnotherNumber;
    }
private:
    std::string m_Name;
    std::string m_Number;
    std::string m_AnotherNumber;
};

void displayWorkers(const std::vector<Employee>& workers) 
{
    size_t fieldSize = 15;
    std::cout << std::setw(20) << "Workers\n";
    std::cout << std::left << std::setw(fieldSize) << "Name" <<
        std::setw(fieldSize) << "Phone" << std::setw(fieldSize) << "Salary";
    std::cout << "\n\n";
    for(auto worker: workers) {
        std::cout << std::setw(fieldSize) << worker.name() << std::setw(fieldSize) 
            << worker.number() << std::setw(fieldSize)
            << worker.anotherNumber() << "\n";
    }
}

int main()
{
    std::vector<Employee>  workers = {
        {"Alex", "22-33-44", "24300"},
        {"Ivan", "55-33-66", "30000"},
        {"Pavel", "22-33-44", "24300"},
        {"Антон", "", "25000"},
        {"Жора", "44-33-11", "25000"}
    };

    displayWorkers(workers);

    return 0;
}

It will be given to you as a homework assignment.

 0
Author: ixSci, 2015-06-07 05:42:14