I want to convert a string to an int and I don't mean ASCII codes.
For a quick run-down, we are passed in an equation as a string. We are to break it down, format it correctly and solve the linear equations. Now, in saying that, I'm not able to convert a string to an int.
I know that the string will be in either the format (-5) or (25) etc. so it's definitely an int. But how do we extract that from a string?
One way I was thinking is running a for/while loop through the string, check for a digit, extract all the digits after that and then look to see if there was a leading '-', if there is, multiply the int by -1.
It seems a bit over complicated for such a small problem though. Any ideas?
In C++11 there are some nice new convert functions from std::string to a number type.
So instead of
atoi( str.c_str() )
you can use
std::stoi( str )
where str is your number as std::string.
There are version for all flavours of numbers:
long stol(string), float stof(string), double stod(string),...
see http://en.cppreference.com/w/cpp/string/basic_string/stol
The possible options are described below:
1. sscanf()
#include <cstdio>
#include <string>
int i;
float f;
double d;
std::string str;
// string -> integer
if(sscanf(str.c_str(), "%d", &i) != 1)
// error management
// string -> float
if(sscanf(str.c_str(), "%f", &f) != 1)
// error management
// string -> double
if(sscanf(str.c_str(), "%lf", &d) != 1)
// error management
This is an error (also shown by cppcheck) because "scanf without field width limits can crash with huge input data on some versions of libc" (see here, and here).
2. std::sto()*
#include <iostream>
#include <string>
int i;
float f;
double d;
std::string str;
try {
// string -> integer
int i = std::stoi(str);
// string -> float
float f = std::stof(str);
// string -> double
double d = std::stod(str);
} catch (...) {
// error management
}
This solution is short and elegant, but it is available only on on C++11 compliant compilers.
3. sstreams
#include <string>
#include <sstream>
int i;
float f;
double d;
std::string str;
// string -> integer
std::istringstream ( str ) >> i;
// string -> float
std::istringstream ( str ) >> f;
// string -> double
std::istringstream ( str ) >> d;
// error management ??
However, with this solution is hard to distinguish between bad input (see here).
4. Boost's lexical_cast
#include <boost/lexical_cast.hpp>
#include <string>
std::string str;
try {
int i = boost::lexical_cast<int>( str.c_str());
float f = boost::lexical_cast<int>( str.c_str());
double d = boost::lexical_cast<int>( str.c_str());
} catch( boost::bad_lexical_cast const& ) {
// Error management
}
However, this is just a wrapper of sstream, and the documentation suggests to use sstream for better error management (see here).
5. strto()*
This solution is very long, due to error management, and it is described here. Since no function returns a plain int, a conversion is needed in case of integer (see here for how this conversion can be achieved).
6. Qt
#include <QString>
#include <string>
bool ok;
std::string;
int i = QString::fromStdString(str).toInt(&ok);
if (!ok)
// Error management
float f = QString::fromStdString(str).toFloat(&ok);
if (!ok)
// Error management
double d = QString::fromStdString(str).toDouble(&ok);
if (!ok)
// Error management
Conclusions
Summing up, the best solution is C++11 std::stoi() or, as a second option, the use of Qt libraries. All other solutions are discouraged or buggy.
std::istringstream ss(thestring);
ss >> thevalue;
To be fully correct you'll want to check the error flags.
use the atoi function to convert the string to an integer:
string a = "25";
int b = atoi(a.c_str());
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
To be more exhaustive (and as it has been requested in comments), I add the solution given by C++17 using std::from_chars.
std::string str = "10";
int number;
std::from_chars(str.data(), str.data()+str.size(), number);
If you want to check whether the conversion was successful:
std::string str = "10";
int number;
auto [ptr, ec] = std::from_chars(str.data(), str.data()+str.size(), number);
assert(ec == std::errc{});
// ptr points to chars after read number
Moreover, to compare the performance of all these solutions, see the following quick-bench link: https://quick-bench.com/q/GBzK53Gc-YSWpEA9XskSZLU963Y
(std::from_chars is the fastest and std::istringstream is the slowest)
1. std::stoi
std::string str = "10";
int number = std::stoi(str);
2. string streams
std::string str = "10";
int number;
std::istringstream(str) >> number
3. boost::lexical_cast
#include <boost/lexical_cast.hpp>
std::string str = "10";
int number;
try
{
number = boost::lexical_cast<int>(str);
std::cout << number << std::endl;
}
catch (boost::bad_lexical_cast const &e) // bad input
{
std::cout << "error" << std::endl;
}
4. std::atoi
std::string str = "10";
int number = std::atoi(str.c_str());
5. sscanf()
std::string str = "10";
int number;
if (sscanf(str .c_str(), "%d", &number) == 1)
{
std::cout << number << '\n';
}
else
{
std::cout << "Bad Input";
}
What about Boost.Lexical_cast?
Here is their example:
The following example treats command line arguments as a sequence of numeric data:
int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector<short> args;
while(*++argv)
{
try
{
args.push_back(lexical_cast<short>(*argv));
}
catch(bad_lexical_cast &)
{
args.push_back(0);
}
}
...
}
Admittedly, my solution wouldn't work for negative integers, but it will extract all positive integers from input text containing integers. It makes use of numeric_only locale:
int main() {
int num;
std::cin.imbue(std::locale(std::locale(), new numeric_only()));
while ( std::cin >> num)
std::cout << num << std::endl;
return 0;
}
Input text:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
Output integers:
5
25
7987
78
9878
The class numeric_only is defined as:
struct numeric_only: std::ctype<char>
{
numeric_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
return &rc[0];
}
};
Complete online demo : http://ideone.com/dRWSj
In C++11 we can use "stoi" function to convert string into a int
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "16";
string s2 = "9.49";
string s3 = "1226";
int num1 = stoi(s1);
int num2 = stoi(s2);
int num3 = stoi(s3);
cout << "stoi(\"" << s1 << "\") is " << num1 << '\n';
cout << "stoi(\"" << s2 << "\") is " << num2 << '\n';
cout << "stoi(\"" << s3 << "\") is " << num3 << '\n';
return 0;
}
It's probably a bit of overkill, but
boost::lexical_cast<int>( theString ) should to the job
quite well.
Well, lot of answers, lot of possibilities. What I am missing here is some universal method that converts a string to different C++ integral types (short, int, long, bool, ...).
I came up with following solution:
#include<sstream>
#include<exception>
#include<string>
#include<type_traits>
using namespace std;
template<typename T>
T toIntegralType(const string &str) {
static_assert(is_integral<T>::value, "Integral type required.");
T ret;
stringstream ss(str);
ss >> ret;
if ( to_string(ret) != str)
throw invalid_argument("Can't convert " + str);
return ret;
}
Here are examples of usage:
string str = "123";
int x = toIntegralType<int>(str); // x = 123
str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int
str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception
Why not just use stringstream output operator to convert a string into an integral type?
Here is the answer:
Let's say a string contains a value that exceeds the limit for intended integral type. For examle, on Wndows 64 max int is 2147483647.
Let's assign to a string a value max int + 1: string str = "2147483648".
Now, when converting the string to an int:
stringstream ss(str);
int x;
ss >> x;
x becomes 2147483647, what is definitely an error: string "2147483648" was not supposed to be converted to the int 2147483647. The provided function toIntegralType spots such errors and throws exception.
In Windows, you could use:
const std::wstring hex = L"0x13";
const std::wstring dec = L"19";
int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "\n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "\n";
}
strtol,stringstream need to specify the base if you need to interpret hexdecimal.
I know this question is really old but I think there's a better way of doing this
#include <string>
#include <sstream>
bool string_to_int(std::string value, int * result) {
std::stringstream stream1, stream2;
std::string stringednumber;
int tempnumber;
stream1 << value;
stream1 >> tempnumber;
stream2 << tempnumber;
stream2 >> stringednumber;
if (!value.compare(stringednumber)) {
*result = tempnumber;
return true;
}
else return false;
}
If I wrote the code right, this will return a boolean value that tells you if the string was a valid number, if false, it wasn't a number, if true it was a number and that number is now result, you would call this this way:
std::string input;
std::cin >> input;
bool worked = string_to_int(input, &result);
You can use std::stringstream, here's an example:
#include <iostream>
#include <sstream>
using namespace std;
string r;
int main() {
cin >> r;
stringstream tmp(r);
int s;
tmp >> s;
cout << s;
return 0;
}
atoi is a built-in function that converts a string to an integer, assuming that the string begins with an integer representation.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
From http://www.cplusplus.com/reference/string/stoi/
// stoi example
#include <iostream> // std::cout
#include <string> // std::string, std::stoi
int main ()
{
std::string str_dec = "2001, A Space Odyssey";
std::string str_hex = "40c3";
std::string str_bin = "-10010110001";
std::string str_auto = "0x7f";
std::string::size_type sz; // alias of size_t
int i_dec = std::stoi (str_dec,&sz);
int i_hex = std::stoi (str_hex,nullptr,16);
int i_bin = std::stoi (str_bin,nullptr,2);
int i_auto = std::stoi (str_auto,nullptr,0);
std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";
std::cout << str_hex << ": " << i_hex << '\n';
std::cout << str_bin << ": " << i_bin << '\n';
std::cout << str_auto << ": " << i_auto << '\n';
return 0;
}
Output:
2001, A Space Odyssey: 2001 and [, A Space Odyssey]
40c3: 16579
-10010110001: -1201
0x7f: 127
My Code:
#include <iostream>
using namespace std;
int main()
{
string s="32"; //String
int n=stoi(s); //Convert to int
cout << n + 1 << endl;
return 0;
}
ll toll(string a){
ll ret=0;
bool minus=false;
for(auto i:a){
if(i=='-'){ minus=true; continue; }
ret*=10;
ret+=(i-'0');
} if(minus) ret*=-1;
return ret;
# ll is defined as, #define ll long long int
# usage: ll a = toll(string("-1234"));
}
To convert from string representation to integer value, we can use std::stringstream.
if the value converted is out of range for integer data type, it returns INT_MIN or INT_MAX.
Also if the string value can’t be represented as an valid int data type, then 0 is returned.
#include
#include
#include
int main() {
std::string x = "50";
int y;
std::istringstream(x) >> y;
std::cout << y << '\n';
return 0;
}
Output:
50
As per the above output, we can see it converted from string numbers to integer number.
Source and more at string to int c++
int stringToInt(std::string value) {
if(value.length() == 0 ) return 0; //tu zmiana..
if (value.find( std::string("NULL") ) != std::string::npos) {
return 0;
}
if (value.find( std::string("null") ) != std::string::npos) {
return 0;
}
int i;
std::stringstream stream1;
stream1.clear();
stream1.str(value);
stream1 >> i;
return i;
};
there is another easy way : suppose you have a character like c='4' therefore you can do one of these steps :
1st : int q
q=(int) c ; (q is now 52 in ascii table ) .
q=q-48; remember that adding 48 to digits is their ascii code .
the second way :
q=c-'0'; the same , character '0' means 48
One line version: long n = strtol(s.c_str(), NULL, base); .
(s is the string, and base is an int such as 2, 8, 10, 16.)
You can refer to this link for more details of strtol.
The core idea is to use strtol function, which is included in cstdlib.
Since strtol only handles with char array, we need to convert string to char array. You can refer to this link.
An example:
#include <iostream>
#include <string> // string type
#include <bitset> // bitset type used in the output
int main(){
s = "1111000001011010";
long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string
cout << s << endl;
cout << t << endl;
cout << hex << t << endl;
cout << bitset<16> (t) << endl;
return 0;
}
which will output:
1111000001011010
61530
f05a
1111000001011010
I think that converting from int to std::string or vice versa needs some special functions like std::stoi()
but if you need to convert a double into a string use to_string() (NOT C#. C# is .ToString() not to_string())
If you wot hard code :)
bool strCanBeInt(std::string string){
for (char n : string) {
if (n != '0' && n != '1' && n != '2' && n != '3' && n != '4' && n != '5'
&& n != '6' && n != '7' && n != '8' && n != '9') {
return false;
}
}
return true;
}
int strToInt(std::string string) {
int integer = 0;
int numInt;
for (char n : string) {
if(n == '0') numInt = 0;
if(n == '1') numInt = 1;
if(n == '2') numInt = 2;
if(n == '3') numInt = 3;
if(n == '4') numInt = 4;
if(n == '5') numInt = 5;
if(n == '6') numInt = 6;
if(n == '7') numInt = 7;
if(n == '8') numInt = 8;
if(n == '9') numInt = 9;
if (integer){
integer *= 10;
}
integer += numInt;
}
return integer;
}
I have a 100 char string with few '\n' characters in it , I want to extract the characters between the first '\n' and the second '\n' and store them in another char array , how can i do that?
please note that i cant use iostreams or vectors as I am using AVR GCC. i can only use strok() or strcpy()
If to use character arrays then you can use the following approach
#include <iostream>
#include <cstring>
int main()
{
char s[100] = "begin\nmiddle\nend";
char t[100];
t[0] = '\0';
if ( char *p = strchr( s, '\n' ) )
{
if ( char *q = strchr( ++p, '\n' ) )
{
std::strncpy( t, p, q - p );
t[q - p] = '\0';
}
else
{
strcpy( t, p );
}
}
std::cout << "\"" << t << "\"" << std::endl;
}
The program output is
"middle"
If you want to get an array of strings separated by the new line character then you can use the following approach
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iterator>
int main()
{
char s[100] = "begin\nmiddle\nend";
std::istringstream is( s );
std::vector<std::string> v( ( std::istream_iterator<std::string>( is ) ),
std::istream_iterator<std::string>() );
for ( const std::string &item : v ) std::cout << '\"' << item << '\"' << std::endl;
}
The program output is
"begin"
"middle"
"end"
But it does not make great sense to use this approach if you need just to copy one substring from one character array to another.
A basic Version is this one:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using std::string;
using std::cout;
void base_ansi_c()
{
const char * source = "one\ntwo\nthree\n";
char target[1024];
const char * c;
for (c = source; c && *c != 0 && *c != '\n'; ++c); //skip until first '\n'
if (c && *c == '\n') ++c; // skip '\n'
int n = 0;
for (; c && *c != 0 && *c != '\n' && n < 1024; ++c, ++n) //copy until second '\n'
{
target[n] = *c;
}
target[n] = 0;
cout << "'" << target << "'\n";
}
void base_cpp_sstream()
{
std::vector<string> cpp_array;
std::string test = "one\ntwo\nthree\n";
std::istringstream is(test);
std::string part;
while (std::getline(is, part, '\n'))
{
cpp_array.emplace_back(part);
std::cout << " " << part << " ";
}
std::cout << "\n";
std::cout << "The second element is: '" << cpp_array.at(1) << "'\n";
}
int main()
{
std::cout << "\nbase_cpp_sstream\n";
base_cpp_sstream();
std::cout << "\nbase_ansi_c\n";
base_ansi_c();
}
If it gets more complex you may want to switch to either boost::tokenizer or boost::spirit::qi.
Since you asked for a different version where the positions are more relevant to the algorithm I added an ansi-c style iterating through the string.
Edit: Some detail about the code above as you requested in the comment. I think explaining this line for (c = source; c && *c != 0 && *c != '\n'; ++c); will be enough to get you started.
The statement c = source just copies the pointer at the beginning of the loop.
At every iteration including the first the following is checked: c && *c != 0 && *c != '\n' The detail here is that c will be dereferenced so it can not be (char*)0. 0 is false, every other value is true. If c is false the chained together values using && are not evaluated. So there is no risk of dereferencing a null pointer. *c != 0 checks if the end of the c-string is reached. In that case no \n was found. *c != '\n' checks if a new line character is reached.
At the end of an iteration the pointer is incremented. ++c this moves the c pointer to the next element of the array. Since c is a char the pointer is incremented by 1. sizeof(char) evaluates to 1. (always). If the array elements were of a different type the increment would also move the pointer to the next element. (does not work with void*).
If '\n' is found there is no increment afterwards. The for loop just ends. since c was declared outside of the loop the value remains preserved and can be used by the subsequent algorithms.
I'm trying to convert Unicode code points to percent encoded UTF-8 code units.
The Unicode -> UTF-8 conversion seems to be working correctly as shown by some testing with Hindi and Chinese characters which show up correctly in Notepad++ with UTF-8 encoding, and can be translated back properly.
I thought the percent encoding would be as simple as adding '%' in front of each UTF-8 code unit, but that doesn't quite work. Rather than the expected %E5%84%A3, I'm seeing %xE5%x84%xA3 (for the unicode U+5123).
What am I doing wrong?
Added code (note that utf8.h belongs to the UTF8-CPP library).
#include <fstream>
#include <iostream>
#include <vector>
#include "utf8.h"
std::string unicode_to_utf8_units(int32_t unicode)
{
unsigned char u[5] = {0,0,0,0,0};
unsigned char *iter = u, *limit = utf8::append(unicode, u);
std::string s;
for (; iter != limit; ++iter) {
s.push_back(*iter);
}
return s;
}
int main()
{
std::ofstream ofs("test.txt", std::ios_base::out);
if (!ofs.good()) {
std::cout << "ofstream encountered a problem." << std::endl;
return 1;
}
utf8::uint32_t unicode = 0x5123;
auto s = unicode_to_utf8_units(unicode);
for (auto &c : s) {
ofs << "%" << c;
}
ofs.close();
return 0;
}
You actually need to convert byte values to the corresponding ASCII strings, for example:
"é" in UTF-8 is the value { 0xc3, 0xa9 }. Please not that these are bytes, char values in C++.
Each byte needs to be converted to: "%C3" and "%C9" respectively.
The best way to do so is to use sstream:
std::ostringstream out;
std::string utf8str = "\xE5\x84\xA3";
for (int i = 0; i < utf8str.length(); ++i) {
out << '%' << std::hex << std::uppercase << (int)(unsigned char)utf8str[i];
}
Or in C++11:
for (auto c: utf8str) {
out << '%' << std::hex << std::uppercase << (int)(unsigned char)c;
}
Please note that the bytes need to be cast to int, because else the << operator will use the litteral binary value.
First casting to unsigned char is needed because otherwise, the sign bit will propagate to the int value, causing output of negative values like FFFFFFE5.
In Pascal Lazarus/Delphi, we have a function QuotedStr() that wraps any string within single quotes.
Here's an example of my current C++ code:
//I need to quote tblCustomers
pqxx::result r = txn.exec( "Select * from \"tblCustomers\" ");
Another one:
//I need to quote cCustomerName
std::cout << "Name: " << r[a]["\"cCustomerName\""];
Similar to the above, I have to frequently double-quote strings. Typing this in is kind of slowing me down. Is there a standard function I can use for this?
BTW, I develop using Ubuntu/Windows with Code::Blocks. The technique used must be compatible across both platforms. If there's no function, this means that I must write one.
C++14 added std::quoted which does exactly that, and more actually: it takes care of escaping quotes and backslashes in output streams, and of unescaping them in input streams. It is efficient, in that it does not create a new string, it's really a IO manipulator. (So you don't get a string, as you'd like.)
#include <iostream>
#include <iomanip>
#include <sstream>
int main()
{
std::string in = "\\Hello \"Wörld\"\\\n";
std::stringstream ss;
ss << std::quoted(in);
std::string out;
ss >> std::quoted(out);
std::cout << '{' << in << "}\n"
<< '{' << ss.str() << "}\n"
<< '{' << out << "}\n";
}
gives
{\Hello "Wörld"\
}
{"\\Hello \"Wörld\"\\
"}
{\Hello "Wörld"\
}
As described in its proposal, it was really designed for round-tripping of strings.
Using C++11 you can create user defined literals like this:
#include <iostream>
#include <string>
#include <cstddef>
// Define user defined literal "_quoted" operator.
std::string operator"" _quoted(const char* text, std::size_t len) {
return "\"" + std::string(text, len) + "\"";
}
int main() {
std::cout << "tblCustomers"_quoted << std::endl;
std::cout << "cCustomerName"_quoted << std::endl;
}
Output:
"tblCustomers"
"cCustomerName"
You can even define the operator with a shorter name if you want, e.g.:
std::string operator"" _q(const char* text, std::size_t len) { /* ... */ }
// ...
std::cout << "tblCustomers"_q << std::endl;
More info on user-defined literals
String str = "tblCustomers";
str = "'" + str + "'";
See more options here
No standard function, unless you count std::basic_string::operator+(), but writing it is trivial.
I'm somewhat confused by what's slowing you down - quoted( "cCustomerName" ) is more characters, no? :>
You could use your own placeholder character to stand for the quote, some ASCII symbol that will never be used, and replace it with " just before you output the strings.
#include <iostream>
#include <string>
struct quoted
{
const char * _text;
quoted( const char * text ) : _text(text) {}
operator std::string () const
{
std::string quotedStr = "\"";
quotedStr += _text;
quotedStr += "\"";
return quotedStr;
}
};
std::ostream & operator<< ( std::ostream & ostr, const quoted & q )
{
ostr << "\"" << q._text << "\"";
return ostr;
}
int main ( int argc, char * argv[] )
{
std::string strq = quoted( "tblCustomers" );
std::cout << strq << std::endl;
std::cout << quoted( "cCustomerName" ) << std::endl;
return 0;
}
With this you get what you want.
What about using some C function and backslash to escape the quotes?
Like sprintf_s:
#define BUF_SIZE 100
void execute_prog() {
//Strings that will be predicted by quotes
string param1 = "C:\\users\\foo\\input file.txt", string param2 = "output.txt";
//Char array with any buffer size
char command[BUF_SIZE];
//Concating my prog call in the C string.
//sprintf_s requires a buffer size for security reasons
sprintf_s(command, BUF_SIZE, "program.exe \"%s\" \"%s\"", param1.c_str(),
param2.c_str());
system(command);
}
Resulting string is:
program.exe "C:\users\foo\input file.txt" "output.txt"
Here is the documentation.
I have tried to find this topic on the web but I couldn't find the one I need.
I have a string of character:
char * tempBuf = "qj";
The result I want is 0x716A, and that value is going to be converted into decimal value.
Is there any function in vc++ that can be used for that?
You can use a stringstream to convert each character to a hexadecimal representation.
#include <iostream>
#include <sstream>
#include <cstring>
int main()
{
const char* tempBuf = "qj";
std::stringstream ss;
const char* it = tempBuf;
const char* end = tempBuf + std::strlen(tempBuf);
for (; it != end; ++it)
ss << std::hex << unsigned(*it);
unsigned result;
ss >> result;
std::cout << "Hex value: " << std::hex << result << std::endl;
std::cout << "Decimal value: " << std::dec << result << std::endl;
}
So if I understood correctly the idea...
#include <stdint.h>
uint32_t charToUInt32(const char* src) {
uint32_t ret = 0;
char* dst = (char*)&ret;
for(int i = 0; (i < 4) && (*src); ++i, ++src)
dst[i] = *src;
return ret;
}
If I understand what you want correctly: just loop over the characters, start to finish; at each character, multiply the sum so far by 256, and add the value of the next character; that gives the decimal value in one shot.
What you are looking for is called "hex encoding". There are a lot of libraries out there that can do that (unless what you were looking for was how to implement one yourself).
One example is crypto++.