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

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;
}

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 *

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.

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.

Related

Unable to understand the syntax errors in c++

I am trying to make a tic tac toe game in c++, but I am getting the following errors in my code(Not completed yet). am I passing the arrays to the function correctly
[Error] invalid conversion from 'char(*)[3]'to 'char'
and
[Error] initializing argument 1 of 'void player_input(char)'
#include <iostream>
using namespace std;
void draw_grid(char display[][3]){
cout<<"Board\n"<<"-------------"<<endl;
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
cout<<"| "<<display[x][y]<<" ";
}
cout<<"|"<<endl<<"-------------";
cout<<endl;
}
}
void player_input(char);
int main(){
char arr[3][3]={
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
draw_grid(arr);
player_input(arr);
draw_grid(arr);
return 0;
}
void player_input(char size[][3]){
char sign;
char number;
cout<<"X or O"<<endl;
cin>>sign;
cout<<"Choose a number\n";
cin>>number;
switch (number){
case '1':
size[0][0]=sign;
break;
case '2':
size[0][1]=sign;
break;
case '3':
size[0][3]=sign;
break;
case '4':
size[1][0]=sign;
break;
case '5':
size[1][1]=sign;
break;
case '6':
size[1][2]=sign;
break;
case '7':
size[2][0]=sign;
break;
case '8':
size[2][1]=sign;
break;
case '9':
size[2][2]=sign;
break;
}
}
void player_input(char);
Your function definition doesn't match the one below void player_input(char size[][3]). Before execution, the compiler tries to match each function call with its appropriate definition. It fails as it only sees the one above (which takes a single character), being matched with player_input(arr); with arr being a 2D array char arr[3][3].
You can modify the line above to make it work:
void player_input(char[3][3]);
Since you're using C++, you should ditch static arrays and consider using one of the modern C++ containers like std::vector.
Here's the fix:
#include <iostream>
using namespace std;
void draw_grid(char display[][3]){
cout<<"Board\n"<<"-------------"<<endl;
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
cout<<"| "<<display[x][y]<<" ";
}
cout<<"|"<<endl<<"-------------";
cout<<endl;
}
}
void player_input(char size[][3]){
char sign;
char number;
cout<<"X or O"<<endl;
cin>>sign;
cout<<"Choose a number\n";
cin>>number;
switch (number){
case '1':
size[0][0]=sign;
break;
case '2':
size[0][1]=sign;
break;
case '3':
size[0][3]=sign;
break;
case '4':
size[1][0]=sign;
break;
case '5':
size[1][1]=sign;
break;
case '6':
size[1][2]=sign;
break;
case '7':
size[2][0]=sign;
break;
case '8':
size[2][1]=sign;
break;
case '9':
size[2][2]=sign;
break;
}
}
int main(){
char arr[3][3]={
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
draw_grid(arr);
player_input(arr);
draw_grid(arr);
return 0;
}
You had 2 declarations of function player_input(). Also if you are not declaring the function type inside main(), you need to place the function definition before main().

Confusion Converting Hexadecimal to Binary in C++

#include <string>
#include <iostream>
using namespace std;
int main() {
string input, numBin = "";
cout << "Enter a hexadecimal number: ";
getline(cin, input);
for (int i = 0; i < input.length(); i++) {
switch (input[i]) {
case 0: numBin.append("0000"); break;
case 1: numBin.append("0001"); break;
case 2: numBin.append("0010"); break;
case 3: numBin.append("0011"); break;
case 4: numBin.append("0100"); break;
case 5: numBin.append("0101"); break;
case 6: numBin.append("0110"); break;
case 7: numBin.append("0111"); break;
case 8: numBin.append("1000"); break;
case 9: numBin.append("1001"); break;
case 'a': numBin.append("1010"); break;
case 'A': numBin.append("1010"); break;
case 'b': numBin.append("1011"); break;
case 'B': numBin.append("1011"); break;
case 'c': numBin.append("1100"); break;
case 'C': numBin.append("1100"); break;
case 'd': numBin.append("1101"); break;
case 'D': numBin.append("1101"); break;
case 'e': numBin.append("1110"); break;
case 'E': numBin.append("1110"); break;
case 'f': numBin.append("1111"); break;
case 'F': numBin.append("1111"); break;
default: break;
}
}
cout << "Your number in binary is " << numBin << ".";
}
This program is supposed to change a hexadecimal input ('input') into a binary result ('numBin'). I don't have much experience using switch statements and do not fully understand the "default" case, so any clarification about that or if I am using it incorrectly would be helpful!
The error I'm getting is on the for loop, and it thorws: comparison between signed and unsigned integer expressions [-Wsign-compare]
In the line:
for (int i = 0; i < input.length(); i++) ...
input.length() returns a size_t, which is a unsigned type.
(see http://www.cplusplus.com/reference/string/string/length/)
Comparing signed and unsigned values is not safe, which is why the compiler warns you, read more about it in this post among many others:
A warning - comparison between signed and unsigned integer expressions
To fix it, simply change to
unsigned int i = 0
The default switch case will be executed when none of the other cases match. You should put some code there that handles incorrect input for example.
case '0':
case '1':
...
Use all characters..not number and characters.
And one ore thing..for(i=0;i<(int) input.length();i++)

C++ Problems modifying string with numbers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I have made a simple encryption function,which encrypts everything except 0-9 numbers (ignoring the special characters).
Here is the code.
#include <iostream>
using namespace std;
void encrypt(char s[])
{
char *ptr;
ptr=s;
while(*ptr)
{
switch (*ptr)
{
case 'a': *ptr='b';
break;
case 'b': *ptr='a';
break;
case 'c': *ptr='z';
break;
case 'd': *ptr='y';
break;
case 'e': *ptr='c';
break;
case 'f': *ptr='d';
break;
case 'g': *ptr='x';
break;
case 'h': *ptr='g';
break;
case 'i': *ptr='i';
break;
case 'j': *ptr='h';
break;
case 'k': *ptr='f';
break;
case 'l': *ptr='j';
break;
case 'm': *ptr='q';
break;
case 'n': *ptr='o';
break;
case 'o': *ptr='p';
break;
case 'p': *ptr='m';
break;
case 'q': *ptr='n';
break;
case 'r': *ptr='l';
break;
case 's': *ptr='k';
break;
case 't': *ptr='x';
break;
case 'u': *ptr='w';
break;
case 'v': *ptr='u';
break;
case 'w': *ptr='v';
break;
case 'x': *ptr='t';
break;
case 'y': *ptr='s';
break;
case 'z': *ptr='r';
break;
case 1: *ptr=5;
break;
case 2: *ptr=6;
break;
case 3: *ptr=0;
break;
case 4: *ptr=1;
break;
case 5: *ptr=2;
break;
case 6: *ptr=7;
break;
case 7: *ptr=4;
break;
case 8: *ptr=3;
break;
case 9: *ptr=8;
break;
case 0: *ptr=9;
break;
default: *ptr=*ptr;
break;
}
*ptr++;
}
*ptr='\0';
}
int main()
{
char password[10];
cout<<"Enter the password\n";
cin>>password;
encrypt(password);
cout<<password<<endl;
return 0;
}
Here is a sample output
sh-4.3$ main
Enter the password
thisisanex!!1234567
xgikikboct!!1234567
You need to use the character '1' not the integer value 1.
So use case '1': instead of case 1: and so on for the other numbers.
As nos said, the character is different from the integer value.
However, looking at your code, it would make a lot more sense to do this:
#include <iostream>
#include <string>
using namespace std;
int main(){
string charset = "abcdefghijklmnopqrstuvwxyz1234567890";
string scrambledcharset = "r5b6ng1fcl8htau9i74kxy0vjw3psemqz2do"; //Whatever order you want
string uIn;
string output;
cout << "Enter your string: ";
cin >> uIn;
cin.ignore();
for(int i = 0; i < uIn.length(); i++){
for(int j = 0; j < charset.length(); j++){
if(uIn[i] == charset[j]){
output += scrambledcharset[j];
}
}
}
cout << "\nScrambled: " << output;
return 0;
}

Empty Character Constant

Is there a way to bypass error C2137 on Visual Studio Community 2015? I am removing characters with stringstream but I do not want to replace them (even with a blank space), I want to erase them so, if I want to remove all 'o' in 'cool' it becomes 'cl' and not 'c l'. I saw in Stroustrup's book he wrote a if (...) ch = ''; but my compiler returns me an error and my best proxy is white space that's still unacceptable.
Here's my function with C2137:
string rem_vow(string& s)
{
for (char& c : s)
{
switch (c)
{
case 'A': case 'a': case 'E': case 'e': case 'I':
case 'i': case 'O': case 'o': case 'U': case 'u':
c = '';
break;
default:
break;
}
}
return s;
}
EDIT:
That's the code I saw in the book:
Thank you in advance
No, in order to remove a character in a string you will have to move the rest of the string one step, you cannot simple replace it with "empty" character. You could use the erase method though, but then you should probably not do that while iterating the string.
What you probably should do is to build a new string as you traverse the original string, something like:
string rem_vow(string const& s)
{
string res;
for (char c : s)
{
switch (c)
{
case 'A': case 'a': case 'E': case 'e': case 'I':
case 'i': case 'O': case 'o': case 'U': case 'u':
//c = ' ';
break;
default:
res.push_back(c);
break;
}
}
return res;
}

Using escape sequence at runtime with C++

I am quiet new with C++ and I need to read an input from a MSVC++ text-field and write it to a file. I need to write \n as a new line to the file and not as \n.
After some researching I found that escape characters only work at compile-time. Is it possible for me to use it on run-time. I am only using C++ for this task.
I might write this a bit differently if I were doing it in C++ today (I wrote this in C around 20 years ago), but it might at least provide a little inspiration:
/*
** Public Domain by Jerry Coffin.
**
** Interprets a string in a manner similar to that the compiler
** does string literals in a program. All escape sequences are
** longer than their translated equivalant, so the string is
** translated in place and either remains the same length or
** becomes shorter.
*/
#include <string.h>
#include <stdio.h>
#include "snip_str.h"
char *translate(char *string)
{
char *here=string;
size_t len=strlen(string);
int num;
int numlen;
while (NULL!=(here=strchr(here,'\\')))
{
numlen=1;
switch (here[1])
{
case '\\':
break;
case 'r':
*here = '\r';
break;
case 'n':
*here = '\n';
break;
case 't':
*here = '\t';
break;
case 'v':
*here = '\v';
break;
case 'a':
*here = '\a';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
numlen = sscanf(here,"%o",&num);
*here = (char)num;
break;
case 'x':
numlen = sscanf(here,"%x",&num);
*here = (char) num;
break;
}
num = here - string + numlen;
here++;
memmove(here,here+numlen,len-num );
}
return string;
}