C++ cannot convert unsigned char to char* when calling my function - c++

In this program I use the function gethostname to get the hostname of the server. However when running this below:
#include <sys/types.h>
#include <sys/socket.h>
⋮
int rc;
int server_sock;
u_char hostname[50];
⋮
rc = gethostname(&hostname,sizeof(hostname));
printf("hostname = %s\n",hostname);
I get the error:
Cannot convert u_char(*)[50] to char* for argument '1' to 'int gethostname(char*, size_t)'

You have an array of the wrong type (u_char instead of char) and you're passing a pointer to the array rather than passing it directly - &hostname is of type u_char(*)[50] - you want just a pointer, which would be just hostname:
The correct approach would be:
char hostname[50];
⋮
rc = gethostname(hostname,sizeof(hostname));

Related

Invalid conversion from ‘const char*’ to ‘char*’ with ```rindex``` function

I want to do something with string using the index and rindex function under c++17, but when I compile the program, this error poped up:
debug.cpp: In function ‘int main()’:
debug.cpp:7:27: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
7 | char* index_first = index(str,'c');
| ~~~~~^~~~~~~~~
| |
| const char*
debug.cpp:9:27: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
9 | char* index_last = rindex(str,'c');
| ~~~~~~^~~~~~~~~
| |
| const char*
Then I checked this program online, every function defines of index and rindex I saw are the same:
char* index(const char* s,int c);
char* rindex(const char* s,int c);
And heres my debug code:
#include <stdio.h>
#include <string.h>
int main()
{
const char* str = "abcdefgabcdefg";
char* index_first = index(str,'c');
printf("the first index is %ld\n",index_first - str + 1);
char* index_last = rindex(str,'c');
printf("the last index is %ld\n",index_last - str + 1);
return 0;
}
I compile it using:
g++ -o debug debug.cpp -std=c++17
I want to know why can't I do that and the right way to use index and rindex functions and (or) the right function defines please.
Heres my environment:
Ubuntu LTS 20.04 (x64)
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Thank you for all the help.
You are trying to assign returned pointers of the type const char * that are used within the functions to pointers of the type char *
Actually the functions you are calling are declared like
const char* index(const char* s,int c);
const char* rindex(const char* s,int c);
In C++ the functions can be overloaded like
const char* index(const char* s,int c);
const char* rindex(const char* s,int c);
and
char* index(char* s,int c);
char* rindex(char* s,int c);
the same way as some other standard C functions as for example the standard C function strchr.
So you should write
const char* index_first = index(str,'c');
printf("the first index is %td\n",index_first - str + 1);
const char* index_last = rindex(str,'c');
printf("the last index is %td\n",index_last - str + 1);
The result of subtracting two pointers has the signed integer type ptrdiff_t. So you need to use the conversion specifier %td instead of %ld.
From the C Standard (7.21.6.1 The fprintf function)
7 The length modifiers and their meanings are:
t Specifies that a following d, i, o, u, x, or X conversion specifier applies to a ptrdiff_t or the corresponding unsigned integer
type argument; or that a following n conversion specifier applies to a
pointer to a ptrdiff_t argument.

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

Invalid cast from type ‘void*’ to function pointer

I want to override open from libc using LD_PRELOAD:
#include <dlfcn.h>
#include <sys/stat.h>
extern "C" {
int open(const char *path, int flags, mode_t mode)
{
int (*originalOpen)(const char *path, int flags, mode_t mode);
originalOpen = reinterpret_cast<decltype(originalOpen)>(dlsym(RTLD_NEXT, "open"));
//originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
//...
return (*originalOpen)(path, flags, mode);
}
}
I compile with g++ -fPIC -shared -o open.so open.cpp -ldl.
Can somebody tell me why the above code works, and why I get the errror:
error: invalid cast from type ‘void*’ to type ‘int(const char*, int, mode_t)’ {aka ‘int(const char*, int, unsigned int)’}
originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
when I initialize originalOpen with the line commented out?
I used gcc version 8.0.1.
Try this code:
originalOpen = reinterpret_cast<decltype(open) *>(dlsym(RTLD_NEXT, "open"));
Decltype gets the type of the function while You want to create function pointer. There is implicit cast from function to pointer of its type but these are not equivalent. This is why version with decltype(original_open) works perfectly - type of original_open is function pointer and not the function.

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++ passing string to varargs

#define LOG(format,...) Logger::Log(format,__VA_ARGS__)
#define STRIP(netIp) GeneralUtils::inet_ntop_(netIp)
string GeneralUtils::inet_ntop_(unsigned int netIp){
char strIP[INET_ADDRSTRLEN];
in_addr sin_addr;
sin_addr.s_addr = netIp;
inet_ntop(AF_INET, &sin_addr.s_addr, strIP, sizeof strIP);
return string(strIP);
}
when calling to :
LOG("src %s dst %s" ,STRIP(src_ip_));
i get compilation error:
cannot pass objects of non-trivially-copyable type ‘std::string {aka struct std::basic_string<char>}’ through ‘...’
I understand that varargs is c compatible , so i cannot send string to it.
Is there a simple way to bypass it?
Will it be correct to fix it like this:
#define STRIP(netIp) GeneralUtils::inet_ntop_(netIp).data()
You can pass const char * instead of std::string. You can take it from std::string by calling c_str()
#define STRIP(netIp) GeneralUtils::inet_ntop_(netIp).data()
is wrong, it will invoke undefined behavior since it doesn't include a terminating zero. Use
#define STRIP(netIp) GeneralUtils::inet_ntop_(netIp).c_str()
instead.