Error using string::erase in C++ - c++

I'm having an error while compiling my C++ program. Below is my code!
#include <pthread.h>
#include "Path.h"
#include "Maze.h"
#include "SubmitMazeSoln.h"
#include "Assignm3_Utils.h"
#include "Assignm3.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
srand(time(NULL));
string random = "0123";
for (int i = 0; i < 4; i++)
{
int x = (rand () % random.size());
char y = random[x];
random.erase(remove(random.begin(), random.end() + y), random.end());
int temp;
if (threadData.threadIDArrayIndex == 0)
{
temp = i;
}
else
{
temp = y - '0';
}
}
The error when I compile my program.
myprog.cpp: In function ‘void* exploreMaze(void*)’:
myprog.cpp:108:56: error: cannot convert ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ to ‘const char*’ for argument ‘1’ to ‘int remove(const char*)’
random.erase(remove(random.begin(), random.end() + y), random.end());
Sorry guys help is deeply appreciated! Thanks!

As DaveB says,
remove(random.begin(), random.end() + y)
should be
remove(random.begin(), random.end(), y)
The error message is confusing because random.end() + y is a valid expression, although it produces an iterator that's way off the end of the container. So the compiler sees a call to the function remove with two arguments, and tries to make sense of it. The compiler sees a function with the signature remove(const char*), and guesses that that's what you meant, then complains that it can't convert the first argument to type const char*.
This confusion wouldn't have happened if you used proper C++ standard library names such as std::remove. using namespace std; strikes again!

Related

How to fix string declaration error in scope

I'm trying to run an interprocess communication program but it says string is not declared in the scope as is and when I add #inlcude I get an error that says:
receiver.cpp:25:35: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
string temp = to_string(argv[0]);
~~~~~~^
In file included from /usr/include/c++/7/string:52:0,
from receiver.cpp:14:
/usr/include/c++/7/bits/basic_string.h:6419:3: note: candidate: std::__cxx11::string std::__cxx11::to_string(unsigned int) <near match>
to_string(unsigned __val)
^~~~~~~~~
receiver.cpp:27:26: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int atoi(const char*)’
int msgid = atoi(temp) //Converts message id from string to integer
^
receiver.cpp:45:32: error: ‘some_data’ was not declared in this scope
if (msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) { //revieces message from message queue
^~~~~~~~~
receiver.cpp:49:29: error: ‘some_data’ was not declared in this scope
printf("You wrote: %s", some_data.some_text);
This is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.H>
#include <cstring.h>
#include <unist.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstdlib>
#inlcude <string>
using namespace std;
struct my_msg_st{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main(int argc, char *argv[0]){
int running =1;
string temp = to_string(argv[0]);
int msgid = atoi(temp);
struct my_msg_st some_data;
long int msg_to_receive = 0;
....
if (strncmp(some_data.some_text, "end", 3) == 0){
running =0;
}
...
exit(0);
}
expecting for the code to print out the message sent from the sender file
Here are some fixes for your issues:
string temp = to_string(argv[0]);
1. to_string converts numbers to string. the argv[0] is a C-style string, not a number.
2. The std::string constructor already has a version to convert from char * to std::string.
atoi(temp)
1. The atoi function takes a parameter of type char * not std::string. You'll need to use atoi(temp.c_str()) or prefer std::ostringstream.
Please review the differences between char arrays (a.k.a. C-Style strings) and the std::string type. Prefer to use std::string, especially in structures.
Carefully read the library function descriptions before using them.
See also std::ostringstream. Since this is C++, prefer to use C++ I/O such as std::cout and operator <<.

While Searching for a key in a map in C++ STL, gives the following error

I have a created a Map with key as string type and the associated value stored in vector. Now I have a string and need to check if the each of the character in the string is present as a key in the map.
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, vector<string>> umap;
umap["1"] = {"a","b","c"};
umap["2"] = {"d","e","f"};
string s = "23";
for(int i=0; i<s.length(); i++) {
if(umap.find(s[i]) != umap.end())
cout<<"Present"<<endl;
else
cout<<"Not Present"<<endl;
}
}
Error:
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::vector<std::__cxx11::basic_string<char> > >::find(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)’
if(umap.find(s[i]) != umap.end())
The error is maybe a bit cryptic. Lets translate it into something human readable.
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::vector<std::__cxx11::basic_string<char> > >::find(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)’
if(umap.find(s[i]) != umap.end())
First std::__cxx11::basic_string<char> is a complicated way to denote a std::string. Then __gnu_cxx::__alloc_traits<std::allocator<char> >::value_type& is an even more complicated way to denote the return type of s[i] which is actually just char&. Putting this together we get
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::string, std::vector<std::string> >::find(char&)’
if(umap.find(s[i]) != umap.end())
I hope now you can see that the error complains that there is no overload of find that would take a char& as parameter.
Instead you should pass a std::string, eg via s.substr(i,1).

C++ Function calling fails

I get the following error when declaring a function:
Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example.cpp:23:5: error: no matching function for call to 'printstats'
printstats(&x, y);
^~~~~~~~~~
/Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example.cpp:10:6: note: candidate function not viable: no known conversion from 'const std::string *' (aka 'const basic_string<char, char_traits<char>, allocator<char> > *') to 'const std::string' (aka 'const basic_string<char, char_traits<char>, allocator<char> >') for 1st argument; remove &
void printstats(const std::string& x, int statnum);
^
/Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example.cpp:12:6: note: candidate function not viable: no known conversion from 'const std::string *' (aka 'const basic_string<char, char_traits<char>, allocator<char> > *') to 'char *' for 1st argument
void printstats(char * x, int stat_num)
^
1 error generated.
[Finished in 0.9s with exit code 1]
[shell_cmd: g++ "/Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example.cpp" -o "/Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example" && "/Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++/c++example"]
[dir: /Users/masterprogrammer/PycharmProjects/WolvesBatsRocks/c++]
[path: /anaconda3/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin]
The function takes two inputs and I am calling it from main.
I am expecting an output which has the following formatting Strength: 7.
Here is the code:
// C program to illustrate
// call by value
#include <stdio.h>
#include <iostream>
#include <ctime> // For time()
#include <cstdlib> // For srand() and rand()
#include <string>
#include <cstring>
void printstats(const std::string& x, int statnum);
void printstats(char * x, int stat_num)
{
printf("%s: %d", x, stat_num);
}
int main(void)
{
const std::string&x = "Strength";
int y = 7;
// Passing parameters
printstats(&x, y);
return 0;
}
Your function prototype void printstats(const std::string& x, int statnum) and function definition void printstats(char * x, int stat_num) expect different parameters.
One expects a const string & as the first parameter and the other expects a char * as the first parameter.
Change both to have the same parameters and make sure your function call passes the appropriate argument(s) to the function.
You can't define an address type, but instead you can pass addresses of other variables which I think neither is what you're aiming to do.
& in method signature means call by reference which basically means inside the function the reference is used to access the actual argument used in the call.
To make it work, define a string and pass it directly.
std::string x= "Strength";
int y = 7;
printstats(x, y);
You really need to read a good introductory C++ book. It seems that you took an example from a C book, and tried to use it in C++ without understanding of what's happening.
I removed the unnecessary includes:
#include <stdio.h>
#include <string>
//Use a reference to string object instead of char pointer
void printstats(const std::string& x, int stat_num)
{
//printf is a C function that expects a C char* straing,
//so we need to convert the C++ string into it
printf("%s: %d", x.c_str(), stat_num);
}
int main(void)
{
//no need for "&" here - it's totally incorrect.
//It is an operation of taking an address of a variable.
const std::string x = "Strength";
int y = 7;
//no need for & here too
printstats(x, y);
return 0;
}
Output:
Strength: 7

c++ error compiling when trying to unlink files

I'm using this code I found on stackoverflow.. this seems to work well for my requirement.
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <conio.h>
int main () {
std::map< std::string, std::string > MyMap;
std::map< std::string, std::string >::iterator MyIterMap;
MyMap["Teste1"] = "map1";
MyMap["Teste2"] = "map2";
MyMap["Teste3"] = "map3";
MyIterMap = MyMap.begin();
while(MyIterMap != MyMap.end() ) {
std::string key = (*MyIterMap).first;
std::cout << "Key: " << key << ", Value: " << MyMap[key] <<std::endl;
MyIterMap++;
}
_getch();
return 0;
}
After each loop, before MyInterMap++ I'm trying to unlink a file based on the value of key as the filename. eg:
unlink ("/tmp/" + key);
When I try and complie I get:
In function ‘int main()’:
error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int unlink(const char*)’
Please can some one advise how I do this ?
Thank you for you time.
You need to pass a pointer to a C string to the unlink function:
const std::string filename = "/tmp/" + key;
unlink(filename.c_str());
It's probably not a problem in this case as unlink is unlikely to store the C string pointer anywhere, but do note that the pointer becomes dangling as soon as the variable filename goes out of scope. If you pass a pointer to a C string obtained from a std::string anywhere, make sure that that pointer does not get used after the std::string is destroyed.
I've resolved it by using
unlink( ("/tmp/" + key).c_str() ) ;
Thanks

Passing 2D array and vector of string as argument to function

I have written two function in which I am passing vector of string to a particular function (PrintStringVector) just to print content and in second function, passing the array of pointers to print the content.The first function is working fine but second one is giving error which is below the my code.
#include <cmath>
#include <stdlib.h>
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
void PrintStringVector(vector<string> & v){
for(int i=0;i<v.size();i++){ cout<<v[i]<<endl;}
}
void PrintStringArray(const char *arr[n]){
for(int i=0;i<n;i++){ cout<<arr[i]<<endl;}
}
int main() {
vector<string> vec;
cin>>n;
const char *arr[n];
for(int i=0;i<n;i++){
string str;
cin>>str;
vec.push_back(str);
arr[i]=str.c_str();
}
PrintStringVector(vec);
PrintStringArray(arr);
return 0;
}
ERRORS:
vinod#vinod-Inspiron-3537:~/Documents/hackerrank$ g++ passing_vector_of_string_or_passing_2d_array.cpp
passing_vector_of_string_or_passing_2d_array.cpp:17:35: error: expected ‘,’ or ‘...’ before ‘arr’
void PrintStringArray(const char* arr[n]){
^
passing_vector_of_string_or_passing_2d_array.cpp: In function ‘void PrintStringArray(const char*)’:
passing_vector_of_string_or_passing_2d_array.cpp:19:33: error: ‘arr’ was not declared in this scope
for(int i=0;i<n;i++){ cout<<arr[i]<<endl;}
^
passing_vector_of_string_or_passing_2d_array.cpp: In function ‘int main()’:
passing_vector_of_string_or_passing_2d_array.cpp:40:25: error: cannot convert ‘const char**’ to ‘const char*’ for argument ‘1’ to ‘void PrintStringArray(const char*)’
PrintStringArray(arr);
const char *arr[n]
This is not a valid declaration (unless n is a constant expression). C++ has no variable length arrays.
"But it works for me inside main!'
That's because g++ implements an extension to C++. This extension does not seem compatible with C variable-length arrays, and is generally buggy. Don't use it.
"But how can I have comparable functionality?"
Use std::vector. Do not use pointers, new[] and delete[] unless you know extremely well why you need these low-level primitives.
In C++ you cannot have VLA (variable length arrays). Since the size of the array arr is only known at runtime you cannot use it as a size of a fixed size array. You should use new to allocate it. E.g.
const char **arr = new const char*[n];
Also modify the function signature like this
void PrintStringArray(const char *arr[]){
or like this
void PrintStringArray(const char **arr){
Finally remember to delete arr once you are finished with it.
delete[] arr;