0

This my first ever code that I used comments and I know the commentation is not perfect. When I attempted to build my code, compiler gives me this error

no matching function for call to 'make_pair(char [len], int&).

I wanted to return two variable with std::pair

Pls notice: I just want to debug this code so do not write your own way to do what I want to at first stage.

I use gcc 5.1 and my OS is windows

/* this program takes an string from user and output its morse code equivalent */

#include <iostream>
#include <cstring>
#include <algorithm>
#include <utility>

using namespace std;

/* getString() is for getting a text with type std::string and converse all the letters in it
to lower case in order to switch case then converse std::string text type to cstring to be able to loop through it with
for loop*/
pair<const char*, int> getString()
{
    string a;
    getline(cin, a);
    // converse all the letters in string a to lower case for switch case
    transform(a.begin(), a.end(), a.begin(), ::tolower);
    int len = a.length() + 1;
    char ch[len];
    strcpy(ch, a.c_str());

    return make_pair(ch, len);  //this line causing error
}
int main() {

    p = pair<const char*, int> getString();
    char ch = p.first;
    int len = p.second;
    string morseCode;

    /*this for loop search in the ch character array and add morse code equivalent of each letter to morseCode
    string Variab*/
    for (int i = 0; i < len; i++)
        switch(ch[i])
        {
        case ' ':
            morseCode += "/ ";
            break;
        case 'a':
            morseCode += ".- ";
            break;
        case 'b':
            morseCode += "-... ";
            break;
        case 'c':
            morseCode += "-.-. ";
            break;
        case 'd':
            morseCode += "-.. ";
            break;
        case 'e':
            morseCode += ". ";
            break;
        case 'f':
            morseCode += "..-. ";
            break;
        case 'g':
            morseCode += "--. ";
            break;
        case 'h':
            morseCode += ".... ";
            break;
        case 'i':
            morseCode += ".. ";
            break;
        case 'j':
            morseCode += ".--- ";
            break;
        case 'k':
            morseCode += "-.- ";
            break;
        case 'l':
            morseCode += ".-.. ";
            break;
        case 'm':
            morseCode += "-- ";
            break;
        case 'n':
            morseCode += "-. ";
            break;
        case 'o':
            morseCode += "--- ";
            break;
        case 'p':
            morseCode += ".--. ";
            break;
        case 'q':
            morseCode += "--.- ";
            break;
        case 'r':
            morseCode += ".-. ";
            break;
        case 's':
            morseCode += "... ";
            break;
        case 't':
            morseCode += "- ";
            break;
        case 'u':
            morseCode += "..- ";
            break;
        case 'v':
            morseCode += "...- ";
            break;
        case 'w':
            morseCode += ".-- ";
            break;
        case 'x':
            morseCode += "-..- ";
            break;
        case 'y':
            morseCode += "-.-- ";
            break;
        case 'z':
            morseCode += "--.. ";
            break;


        }
        cout << morseCode;
    return 0;
}
coder
  • 6,805
  • 15
  • 34
  • 47
JooJe
  • 1
  • 1
    Whole bunch of weird in there, but `make_pair` depends on compile time knowledge. `len` is not known at compile time. – user4581301 Jul 03 '18 at 04:55
  • Look into using `std::vector` instead of `char[len]`. It's a container and you can use it in `std::make_pair` – doug Jul 03 '18 at 05:32

3 Answers3

1

You can't return a stack allocated character array as a const char* as the array will no longer exist after the end of your function and the pointer will point to an invalid location.

Also note that creating an array on the stack that is of variable size is a gcc extension which is non-standard.

It would be much simpler to just return std::string then you wouldn't need a pair at all.

As an aside I think to solve the issue with make pair you need to cast your character array to const char *

Alan Birtles
  • 22,711
  • 4
  • 22
  • 44
0

Sticking to the compiler error, I produce the following minimal example.

#include <algorithm>
#include <utility>

using namespace std;

int main() {

    int len = 10;
    char ch[len];
    make_pair(ch, len);  //this line causing error
}

make_pair is a function template that is going to create a function at compile time that is based on a variable, len, that will only be known at runtime. This stems from char ch[len]; being a variable length array, something that is illegal in standard C++ because of problems like this. You should see the horror that is sizeof after variable length arrays are though with it, but that's getting off topic.

The best solution is to stick to std::string throughout, but in keeping with producing a pair<const char*, int>,

int main() {

    int len = 10;
    char * ch = new char[len];
    make_pair(ch, len);
}

Remember to delete the allocated storage when you are done with it. This will also fix the bug spotted by Alan Birtles. Note: You could also use a smart pointer, but if you're willing to go that far, go a quarter as far and just use std::string.

Addendum

In

p = pair<const char*, int> getString();

p needs a type. Currently that type is in the wrong place

pair<const char*, int> p = getString();

It is also a good place to use auto.

auto p = getString();

Next

char ch = p.first;

p.first is a const char *, not a char.

That should get your code compiling. The rest is logic errors.

Community
  • 1
  • 1
user4581301
  • 29,019
  • 5
  • 26
  • 45
0

You can use std::string.

This way you can use the size() method of std::string to get its length.

You can also return a local std::string variable and this will use move semantics to get you the correct return value.

If you do want to use std::pair you can still pass in an std::string to it - std::pair<std::string, int>, however if int represents the string length, it is not needed.

Superman
  • 109
  • 1
  • 6