atoi() conversion error - c++

atoi() is giving me this error:
error C2664: 'atoi' : cannot convert parameter 1 from 'char' to 'const char *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
from this line:
int pid = atoi( token.at(0) );
where token is a vector
how can i go around this?

token.at(0) is returning a single char, but atoi() is expecting a string (a pointer to a char.) Either convert the single character to a string, or to convert a single digit char into the number it represents you can usually* just do this:
int pid = token.at(0) - '0';
* The exception is when the charset doesn't encode digits 0-9 in order which is extremely rare.

You'll have to create a string:
int pid = atoi(std::string(1, token.at(0)).c_str());
... assuming that token is a std::vector of char, and using std::string's constructor that accepts a single character (and the number of that character that the string will contain, one in this case).

Your example is incomplete, as you don't say the exact type of the vector. I assume it is std::vector<char> (that, perhaps, you filled with each char from a C string).
My solution would be to convert it again on char *, which would give the following code:
void doSomething(const std::vector & token)
{
char c[2] = {token.at(0), 0} ;
int pid = std::atoi(c) ;
}
Note that this is a C-like solution (i.e., quite ugly in C++ code), but it remains efficient.

const char tempChar = token.at(0);
int tempVal = atoi(&tempChar);

stringstream ss;
ss << token.at(0);
int pid = -1;
ss >> pid;
Example:
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
using namespace std;
vector<char> token(1, '8');
stringstream ss;
ss << token.at(0);
int pid = -1;
ss >> pid;
if(!ss) {
cerr << "error: can't convert to int '" << token.at(0) << "'" << endl;
}
cout << pid << endl;
return 0;
}

Related

Different behaviors in strringstream given std::hex, uint8_t vs int

I suppose the fact that uint8_t is really just an alias for char means that when the characters in the stringstream get read back in, they are stored natively, i.e. the ascii code for the character, whereas if the char is input to an int, with std::hex specified, it gets read in as a hex digit converted to base 10.
This is a small example exhibiting the behavior, but the reason I'm asking is because I started out under the assumption that specifying an output vector of unit8_t was the right approach, as I need to later feed this vector as an array to a C function as a byte vector (you pass it in as a void pointer and it figures out what do to with it somehow). So I figured reading in pairs of input chars into a string stream and then out into a uint8_t would help me skip manually bitshifting. Is there a way of keeping the idea of reading into a uint8_t but evoking the handling of an int? Can I cast to int at the point of the read from the stringstream? Or what?
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdint>
int main (int argc, char** argv) {
uint8_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
std::cout << "uint8:" << (int)n << std::endl;
int m = 0;
std::stringstream tt;
tt << 'F';
tt >> std::hex >> m;
std::cout << "int:" << std::hex << m << std::endl;
return 0;
}
output
uint8:70
int:f
There are operator>> overloads for char, signed char and unsigned char, which all read a single character from the stream. A uint8_t argument selects the unsigned char overload as the best match, reading F as a character (ASCII code 70 or 0x46).
To match an integer extraction operator>> overload, use an argument of type short or bigger (for example, uint16_t):
uint16_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
Can I cast to int at the point of the read from the stringstream?
No. The argument is taken by reference, which in function calls works as a pointer. Type punning a uint8_t argument as (int&) will invoke undefined behavior. Just use a bigger type instead.

string (from substr) conversion to unsigned int

I have a string which actually contains a number and a string, separated by ,, for instance "12,fooBar".
I would like to put it into separated variables, i.e. the number into unsigned int myNum and the string into std::string myStr.
I have the following snipped of code:
size_t pos1=value.find(',');
std::cout << value.substr(0, pos1) << " and "
<< (value.substr(0, pos1)).c_str() << std::endl;
This yields 12 and 1. Anything I missed here? What happend to the 2 in the second part?
Note: I isolated the problem to this snipped of code. I need c_str() to pass it to atoi to get the unsigend int. Here I don't want to print the second part.
Update: I actually get the string from levelDB Get. If I put a test string like I put here, it works.
The posted code produces the same substring: value.substr(0, pos1). Note that std::string::substr() does not modify the object, but returns a new std::string.
Example:
#include <iostream>
#include <string>
int main ()
{
std::string value ="12,fooBar";
unsigned int myNum;
std::string myStr;
const size_t pos1 = value.find(',');
if (std::string::npos != pos1)
{
myNum = atoi(value.substr(0, pos1).c_str());
myStr = value.substr(pos1 + 1);
}
std::cout << myNum << " and "
<< myStr << std::endl;
return 0;
}
Output:
12 and fooBar
EDIT:
If the unsigned int is the only piece required then the following will work:
unsigned int myNum = atoi(value.c_str());
as atoi() will stop at the first non-digit character (excluding optional leading - or +), in this case the ,.
The cleanest C++ style solution to this problem is to use a stringstream.
#include <sstream>
// ...
std::string value = "12,fooBar";
unsigned int myNum;
std::string myStr;
std::stringstream myStream(value);
myStream >> myNum;
myStream.ignore();
myStream >> myStr;
Your second substr should be value.substr(pos1+1,value.length())
One more option is using std::from_chars function from the 17th standard (< charconv > header):
int x;
from_chars(&s[i], &s.back(), x); // starting from character at index i parse
// the nearest interger till the second char pointer
There are different overloads for different types of value x (double etc.).

C++ string to double conversion

Usually when I write anything in C++ and I need to convert a char into an int I simply make a new int equal to the char.
I used the code(snippet)
string word;
openfile >> word;
double lol=word;
I receive the error that
Code1.cpp cannot convert `std::string' to `double' in initialization
What does the error mean exactly? The first word is the number 50. Thanks :)
You can convert char to int and viceversa easily because for the machine an int and a char are the same, 8 bits, the only difference comes when they have to be shown in screen, if the number is 65 and is saved as a char, then it will show 'A', if it's saved as a int it will show 65.
With other types things change, because they are stored differently in memory. There's standard function in C that allows you to convert from string to double easily, it's atof. (You need to include stdlib.h)
#include <stdlib.h>
int main()
{
string word;
openfile >> word;
double lol = atof(word.c_str()); /*c_str is needed to convert string to const char*
previously (the function requires it)*/
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << stod(" 99.999 ") << endl;
}
Output: 99.999 (which is double, whitespace was automatically stripped)
Since C++11 converting string to floating-point values (like double) is available with functions:
stof - convert str to a float
stod - convert str to a double
stold - convert str to a long double
As conversion of string to int was also mentioned in the question, there are the following functions in C++11:
stoi - convert str to an int
stol - convert str to a long
stoul - convert str to an unsigned long
stoll - convert str to a long long
stoull - convert str to an unsigned long long
The problem is that C++ is a statically-typed language, meaning that if something is declared as a string, it's a string, and if something is declared as a double, it's a double. Unlike other languages like JavaScript or PHP, there is no way to automatically convert from a string to a numeric value because the conversion might not be well-defined. For example, if you try converting the string "Hi there!" to a double, there's no meaningful conversion. Sure, you could just set the double to 0.0 or NaN, but this would almost certainly be masking the fact that there's a problem in the code.
To fix this, don't buffer the file contents into a string. Instead, just read directly into the double:
double lol;
openfile >> lol;
This reads the value directly as a real number, and if an error occurs will cause the stream's .fail() method to return true. For example:
double lol;
openfile >> lol;
if (openfile.fail()) {
cout << "Couldn't read a double from the file." << endl;
}
If you are reading from a file then you should hear the advice given and just put it into a double.
On the other hand, if you do have, say, a string you could use boost's lexical_cast.
Here is a (very simple) example:
int Foo(std::string anInt)
{
return lexical_cast<int>(anInt);
}
The C++ way of solving conversions (not the classical C) is illustrated with the program below. Note that the intent is to be able to use the same formatting facilities offered by iostream like precision, fill character, padding, hex, and the manipulators, etcetera.
Compile and run this program, then study it. It is simple
#include "iostream"
#include "iomanip"
#include "sstream"
using namespace std;
int main()
{
// Converting the content of a char array or a string to a double variable
double d;
string S;
S = "4.5";
istringstream(S) >> d;
cout << "\nThe value of the double variable d is " << d << endl;
istringstream("9.87654") >> d;
cout << "\nNow the value of the double variable d is " << d << endl;
// Converting a double to string with formatting restrictions
double D=3.771234567;
ostringstream Q;
Q.fill('#');
Q << "<<<" << setprecision(6) << setw(20) << D << ">>>";
S = Q.str(); // formatted converted double is now in string
cout << "\nThe value of the string variable S is " << S << endl;
return 0;
}
Prof. Martinez
Coversion from string to double can be achieved by
using the 'strtod()' function from the library 'stdlib.h'
#include <iostream>
#include <stdlib.h>
int main ()
{
std::string data="20.9";
double value = strtod(data.c_str(), NULL);
std::cout<<value<<'\n';
return 0;
}
#include <string>
#include <cmath>
double _string_to_double(std::string s,unsigned short radix){
double n = 0;
for (unsigned short x = s.size(), y = 0;x>0;)
if(!(s[--x] ^ '.')) // if is equal
n/=pow(10,s.size()-1-x), y+= s.size()-x;
else
n+=( (s[x]-48) * pow(10,s.size()-1-x - y) );
return n;
}
or
//In case you want to convert from different bases.
#include <string>
#include <iostream>
#include <cmath>
double _string_to_double(std::string s,unsigned short radix){
double n = 0;
for (unsigned short x = s.size(), y = 0;x>0;)
if(!(s[--x] ^ '.'))
n/=pow(radix,s.size()-1-x), y+= s.size()-x;
else
n+=( (s[x]- (s[x]<='9' ? '0':'0'+7) ) * pow(radix,s.size()-1-x - y) );
return n;
}
int main(){
std::cout<<_string_to_double("10.A",16)<<std::endl;//Prints 16.625
std::cout<<_string_to_double("1001.1",2)<<std::endl;//Prints 9.5
std::cout<<_string_to_double("123.4",10)<<std::endl;//Prints 123.4
return 0;
}

how to convert a hexadecimal string to a corresponding integer in c++?

i have a unicode mapping stored in a file.
like this line below with tab delimited.
a 0B85 0 0B85
second column is a unicode character. i want to convert that to 0x0B85 which is to be stored in int variable.
how to do it?
You've asked for C++, so here is the canonical C++ solution using streams:
#include <iostream>
int main()
{
int p;
std::cin >> std::hex >> p;
std::cout << "Got " << p << std::endl;
return 0;
}
You can substitute std::cin for a string-stream if that's required in your case.
You could use strtol, which can parse numbers into longs, which you can then assign to your int. strtol can parse numbers with any radix from 2 to 36 (i.e. any radix that can be represented with alphanumeric charaters).
For example:
#include <cstdlib>
using namespace std;
char *token;
...
// assign data from your file to token
...
char *err; // points to location of error, or final '\0' if no error.
int x = strtol(token, &err, 16); // convert hex string to int

How can I make this declaration work?

EDIT: I also got an answer to make sector a vector of vectors:
vector<vector<char>>sector;
and that gets rid of the rest of my errors.
EDIT: I've made sector an array of pointers as someone suggested, and still get three errors:
EDIT: I have edited the program, but it has not fixed all of the errors:
I have this section of a program:
char* load_data(int begin_point,int num_characters);
ifstream mapdata("map_data.txt");
const int maxx=atoi(load_data(0,2));
const int maxy=atoi(load_data(2,2));
char** sector=new char[maxx][maxy];
char* load_data(int begin_point,int num_characters)
{
seekg(begin_point);
char* return_val=new char[num_characters+1];
mapdata.getline(return_val,num_characters);
return return_val;
}
And I get these errors:
line 5>error C2540: non-constant expression as array bound
line 5>error C2440: 'initializing' : cannot convert from 'char (*)[1]' to 'char **'
line 14>error C3861: 'seekg': identifier not found
per seekg: yes I know I have to include fstream, I included that in main.cpp, this is a separate .h file also included in main.cpp.
How do I fix the errors? Specifically, how to I fix the errors while keeping all my variables global?
Also, if it helps, this is map_data.txt:
10
10
00O
99!
1
55X
19
What is a question?
18
This is an answer
1
1
2
1
Well,
function load_data(int,int) returns a char.
You are passing that char to the atoi function, that takes a char*. In addition to that, you are probably not including stdlib.h header file!!
#include <cstdlib>
int atoi(const char*);
If you dont wan't to include stdlib.h, then you could declare atoi as extern, but be aware when you compile this module.
extern int atoi(const char*)
Take into account that the argument of atoi function must be a null-terminated string.
In order for your code to work, you should make function load data return a char*, not a char.
char* load_data(int,int);
So, now you could do
//notice these aren't const, they rely on non-compile time available data.
int maxx = atoi (load_data(....));
int maxy = atoi (load_data(....));
If you are in C++, load_data function could return a std::string.
std::string load_data(int,int)
and then use c_str() method, which returns a C-String from a C++ string.
const char* std::string:c_str()
int maxx = atoi(load_data(....).c_str());
int maxy = atoi(load_data(....).c_str());
In addition to that, you shouldn't
(regarding
line 5>error C2540: non-constant expression as array bound
line 5>error C2440: 'initializing' : cannot convert from 'char (*)[1]' to 'char **'
)
char sector[maxx][maxy];
You should
char** sector = new char[maxx][maxy]();
and dont forget to free this memory
delete[](sector);
You can't return a pointer to a stack variable. And arrays need to be returned as pointer types.
Try:
char* load_data(int begin_point,int num_characters)
{
seekg(begin_point);
char* return_val = new char[num_characters+1];
mapdata.getline(return_val, num_characters);
return return_val;
}
char* foo = load_data(...);
...
delete [] foo;
I'm not quite sure what is the goal of your exercise. But if you want to read 'stuff' from file and get it in format that you expect (like int, strings ...) you can just use operator>> and getline like this:
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream ifs("data.txt");
if (!ifs.is_open()) return 0;
int maxx;
int maxy;
ifs >> maxx >> maxy;
cout << maxx << " " << maxy << endl;
// ----
char OO_0[4]; // can use char[] or string, see next
ifs >> OO_0;
OO_0[sizeof(OO_0)] = 0;
cout << OO_0 << endl;
// ----
string _99;
ifs >> _99;
cout << _99 << endl;
int one;
string _55_X;
int _19;
string what_is;
ifs >> one >> _55_X >> _19 >> ws;
// ws gets rid of white space at the end of the line ...
// this is because getline would only read that ws up to eol
getline(ifs,what_is);
cout << one << " " << _55_X << " " << _19 << " " << what_is << endl;
ifs.close();
}
And you get output like this:
10 12
00O
99!
1 55X 19 What is a question?
Is that what you were after? NOTE: I'm using c++ because I noticed you mentioned "main.cpp"