C++ Function calling fails - c++

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

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 <<.

User defined integer literal not found

I am trying to create a user defined literal but get an error message when using it.
GCC says
unable to find numeric literal operator ‘operator""_uint’
while clang tells me
error: no matching literal operator for call to 'operator""_uint' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
I reduced the code to following MCVE:
#include <cinttypes>
unsigned int operator"" _uint(char const *, std::size_t) { return 0; }
int main() {
return 1_uint;
}
Which gives the mentioned error as you can see on ideone.
As you can read in detail on cppreference.com there is a multitude of different versions for literal operators.
The one in the OP is used exclusively for string literals and won't be available for integers. Instead the "fallback" version for integers which expects only a const char* without a second std::size_t parameter:
#include <cinttypes>
unsigned int operator"" _uint(char const *) { return 0; }
int main() {
return 1_uint;
}
Which works on ideone.

Error using string::erase in 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!

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;

POSIX Thread Addition on XCode

The program should get arguments from a command line, and add the arguments via posix threads. But Xcode successfully builds it, but gives no output. Is there something wrong with this code.
Thanks
#include <iostream>
#include <pthread.h>
using namespace std;
void *Add(void *threadid){
long tid;
tid =(long)threadid;
long sum=0;
sum=sum+tid;
printf("%ld.\n",sum);
pthread_exit(NULL);
}
void *Print(void *threadid){
long tid;
tid =(long)threadid;
printf("%ld.\n",tid);
pthread_exit(NULL);
}
int main (int argc, char const *argv[])
{
if(argc<6){
printf("you need more arguments");
return -1;
}
long real[5];
pthread_t athread,bthread;
for (int x=1;x<=5;x++)
real[x-1]=atol(argv[x]);
for(int y=1;y<=5;y++)
pthread_create(athread[y],NULL,Add,(void *)&real[y]);
for(int y=1;y<=5;y++)
pthread_create(bthread[y],NULL,Print,(void *)&real[y]);
pthread_exit(NULL);
return 0;
}
First of all I think you should check if pthread_create method was success.
I don't have expirience in pthread under Apple, but based on that code I think you have problem with thread creation.
First of all, printf is defined in stdio.h and not in iostream. If you'd like to do it the C++ way with iostream, then cout << "Blabla " << var << endl; should be used instead.
Second, you are calling pthread_create with wrong arguments. As defined athread and bthread are not arrays but you use them as such. I am not entirely sure why this would even compile since pthread_create expects pthread_t* as first argument and you are providing *pthread_t. If the code ever compiles, it will most likely crash when run.
Third, you are not joining the adder threads. This means that your print threads could start before the adder threads have finished.
Fourth, you are summing into local variables. You are supposed to sum into a global one. Don't forget to guard the access to it by a mutex or something.
Fifth, arguments to the thread routines are wrong. You are passing pointer to the value and not the value itself and later reinterpreting the pointer as the value itself. You would most likely want to use (void *)real[y] and not (void *)&real[y]. Mind that casting long to void * doesn't work on all systems. On Mac OS X both long and void * are of the same length (either 32 or 64 bits) but this is not true in general.
Edited: Your code doesn't even compile on OS X:
$ g++ -o t.x t.cpp
t.cpp: In function ‘int main(int, const char**)’:
t.cpp:37: error: cannot convert ‘_opaque_pthread_t’ to ‘_opaque_pthread_t**’ for argument ‘1’ to ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
t.cpp:40: error: cannot convert ‘_opaque_pthread_t’ to ‘_opaque_pthread_t**’ for argument ‘1’ to ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
$ clang -o t.x t.cpp
t.cpp:37:5: error: no matching function for call to 'pthread_create'
pthread_create(athread[y],NULL,Add,(void *)&real[y]);
^~~~~~~~~~~~~~
/usr/include/pthread.h:304:11: note: candidate function not viable: no known
conversion from 'struct _opaque_pthread_t' to 'pthread_t *' (aka
'_opaque_pthread_t **') for 1st argument;
int pthread_create(pthread_t * __restrict,
^
t.cpp:40:5: error: no matching function for call to 'pthread_create'
pthread_create(bthread[y],NULL,Print,(void *)&real[y]);
^~~~~~~~~~~~~~
/usr/include/pthread.h:304:11: note: candidate function not viable: no known
conversion from 'struct _opaque_pthread_t' to 'pthread_t *' (aka
'_opaque_pthread_t **') for 1st argument;
int pthread_create(pthread_t * __restrict,
^
2 errors generated.
Don't you even see the error messages that XCode is providing?