Related
When trying to define the char:
char q = '§';
clion throws an error: "Character too large for enclosing character literal type". This is weird as if I look up the ascii conversion of § it is just 167.
If I use:
char c;
std::string q = "§";
for (char el:q) {
c = el;
std::cout << c;
}
the output reads: §
and:
int c;
std::string q = "§";
for (char el:q) {
c = (int) el;
std::cout << c;
}
outputs: -62-89
So it seems that the character overflows the char type
I am implenting RSA encryption using unsinged long long int instead of int in this case and the overflow still occurs which corrupts the decrypted data. How can I convert this character and potentially others that may overflow the char type into their respective ascii value (for this example (char)'§' should return 167).
conversion with unsigned long long int:
#define ull unsigned long long int
int main() {
ull c;
std::string q = "§";
for (char el:q) {
c = (ull) el;
std::cout << c;
}
}
output: 1844674407370955155418446744073709551527
using wchar_t also did not fix the issue.
One way to go around it is to use unicode string:
auto q = u"\u00A7";
Unicode strings (u for 16-bit and U for 32-bit) can in general be used similarly to normal std::string type but when you iterate over it or index into it, you'll have the corresponding character type: char16_t or char32_t.
I want to convert a hex string to a 32 bit signed integer in C++.
So, for example, I have the hex string "fffefffe". The binary representation of this is 11111111111111101111111111111110. The signed integer representation of this is: -65538.
How do I do this conversion in C++? This also needs to work for non-negative numbers. For example, the hex string "0000000A", which is 00000000000000000000000000001010 in binary, and 10 in decimal.
use std::stringstream
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
the following example produces -65538 as its result:
#include <sstream>
#include <iostream>
int main() {
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;
}
In the new C++11 standard, there are a few new utility functions which you can make use of! specifically, there is a family of "string to number" functions (http://en.cppreference.com/w/cpp/string/basic_string/stol and http://en.cppreference.com/w/cpp/string/basic_string/stoul). These are essentially thin wrappers around C's string to number conversion functions, but know how to deal with a std::string
So, the simplest answer for newer code would probably look like this:
std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);
NOTE: Below is my original answer, which as the edit says is not a complete answer. For a functional solution, stick the code above the line :-).
It appears that since lexical_cast<> is defined to have stream conversion semantics. Sadly, streams don't understand the "0x" notation. So both the boost::lexical_cast and my hand rolled one don't deal well with hex strings. The above solution which manually sets the input stream to hex will handle it just fine.
Boost has some stuff to do this as well, which has some nice error checking capabilities as well. You can use it like this:
try {
unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
// whatever you want to do...
}
If you don't feel like using boost, here's a light version of lexical cast which does no error checking:
template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
T2 out;
std::stringstream ss;
ss << in;
ss >> out;
return out;
}
which you can use like this:
// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef");
For a method that works with both C and C++, you might want to consider using the standard library function strtol().
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "abcd";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) { //my bad edit was here
cout << "not a number" << endl;
}
else {
cout << n << endl;
}
}
Andy Buchanan, as far as sticking to C++ goes, I liked yours, but I have a few mods:
template <typename ElemT>
struct HexTo {
ElemT value;
operator ElemT() const {return value;}
friend std::istream& operator>>(std::istream& in, HexTo& out) {
in >> std::hex >> out.value;
return in;
}
};
Used like
uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");
That way you don't need one impl per int type.
Working example with strtoul will be:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "fffefffe";
char * p;
long n = strtoul( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
strtol converts string to long. On my computer numeric_limits<long>::max() gives 0x7fffffff. Obviously that 0xfffefffe is greater than 0x7fffffff. So strtol returns MAX_LONG instead of wanted value. strtoul converts string to unsigned long that's why no overflow in this case.
Ok, strtol is considering input string not as 32-bit signed integer before convertation. Funny sample with strtol:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "-0x10002";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
The code above prints -65538 in console.
Here's a simple and working method I found elsewhere:
string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);
Please note that you might prefer using unsigned long integer/long integer, to receive the value.
Another note, the c_str() function just converts the std::string to const char* .
So if you have a const char* ready, just go ahead with using that variable name directly, as shown below [I am also showing the usage of the unsigned long variable for a larger hex number. Do not confuse it with the case of having const char* instead of string]:
const char *hexString = "7FFEA5"; //Just to show the conversion of a bigger hex number
unsigned long hexNumber; //In case your hex number is going to be sufficiently big.
sscanf(hexString, "%x", &hexNumber);
This works just perfectly fine (provided you use appropriate data types per your need).
I had the same problem today, here's how I solved it so I could keep lexical_cast<>
typedef unsigned int uint32;
typedef signed int int32;
class uint32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator uint32() const { return value; }
friend std::istream& operator>>( std::istream& in, uint32_from_hex& outValue )
{
in >> std::hex >> outValue.value;
}
};
class int32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator int32() const { return static_cast<int32>( value ); }
friend std::istream& operator>>( std::istream& in, int32_from_hex& outValue )
{
in >> std::hex >> outvalue.value;
}
};
uint32 material0 = lexical_cast<uint32_from_hex>( "0x4ad" );
uint32 material1 = lexical_cast<uint32_from_hex>( "4ad" );
uint32 material2 = lexical_cast<uint32>( "1197" );
int32 materialX = lexical_cast<int32_from_hex>( "0xfffefffe" );
int32 materialY = lexical_cast<int32_from_hex>( "fffefffe" );
// etc...
(Found this page when I was looking for a less sucky way :-)
Cheers,
A.
just use stoi/stol/stoll
for example:
std::cout << std::stol("fffefffe", nullptr, 16) << std::endl;
output: 4294901758
This worked for me:
string string_test = "80123456";
unsigned long x;
signed long val;
std::stringstream ss;
ss << std::hex << string_test;
ss >> x;
// ss >> val; // if I try this val = 0
val = (signed long)x; // However, if I cast the unsigned result I get val = 0x80123456
Try this. This solution is a bit risky. There are no checks. The string must only have hex values and the string length must match the return type size. But no need for extra headers.
char hextob(char ch)
{
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
return 0;
}
template<typename T>
T hextot(char* hex)
{
T value = 0;
for (size_t i = 0; i < sizeof(T)*2; ++i)
value |= hextob(hex[i]) << (8*sizeof(T)-4*(i+1));
return value;
};
Usage:
int main()
{
char str[4] = {'f','f','f','f'};
std::cout << hextot<int16_t>(str) << "\n";
}
Note: the length of the string must be divisible by 2
For those looking to convert number base for unsigned numbers, it is pretty trivial to do yourself in both C/C++ with minimal dependency (only operator not provided by the language itself is pow() function).
In mathematical terms, a positive ordinal number d in base b with n number of digits can be converted to base 10 using:
Example: Converting base 16 number 00f looks like:
= 0*16^2 + 0*16^1 + 16*16^0 = 15
C/C++ Example:
#include <math.h>
unsigned int to_base10(char *d_str, int len, int base)
{
if (len < 1) {
return 0;
}
char d = d_str[0];
// chars 0-9 = 48-57, chars a-f = 97-102
int val = (d > 57) ? d - ('a' - 10) : d - '0';
int result = val * pow(base, (len - 1));
d_str++; // increment pointer
return result + to_base10(d_str, len - 1, base);
}
int main(int argc, char const *argv[])
{
char n[] = "00f"; // base 16 number of len = 3
printf("%d\n", to_base10(n, 3, 16));
}
I want to convert a hex string to a 32 bit signed integer in C++.
So, for example, I have the hex string "fffefffe". The binary representation of this is 11111111111111101111111111111110. The signed integer representation of this is: -65538.
How do I do this conversion in C++? This also needs to work for non-negative numbers. For example, the hex string "0000000A", which is 00000000000000000000000000001010 in binary, and 10 in decimal.
use std::stringstream
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
the following example produces -65538 as its result:
#include <sstream>
#include <iostream>
int main() {
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;
}
In the new C++11 standard, there are a few new utility functions which you can make use of! specifically, there is a family of "string to number" functions (http://en.cppreference.com/w/cpp/string/basic_string/stol and http://en.cppreference.com/w/cpp/string/basic_string/stoul). These are essentially thin wrappers around C's string to number conversion functions, but know how to deal with a std::string
So, the simplest answer for newer code would probably look like this:
std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);
NOTE: Below is my original answer, which as the edit says is not a complete answer. For a functional solution, stick the code above the line :-).
It appears that since lexical_cast<> is defined to have stream conversion semantics. Sadly, streams don't understand the "0x" notation. So both the boost::lexical_cast and my hand rolled one don't deal well with hex strings. The above solution which manually sets the input stream to hex will handle it just fine.
Boost has some stuff to do this as well, which has some nice error checking capabilities as well. You can use it like this:
try {
unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
// whatever you want to do...
}
If you don't feel like using boost, here's a light version of lexical cast which does no error checking:
template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
T2 out;
std::stringstream ss;
ss << in;
ss >> out;
return out;
}
which you can use like this:
// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef");
For a method that works with both C and C++, you might want to consider using the standard library function strtol().
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "abcd";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) { //my bad edit was here
cout << "not a number" << endl;
}
else {
cout << n << endl;
}
}
Andy Buchanan, as far as sticking to C++ goes, I liked yours, but I have a few mods:
template <typename ElemT>
struct HexTo {
ElemT value;
operator ElemT() const {return value;}
friend std::istream& operator>>(std::istream& in, HexTo& out) {
in >> std::hex >> out.value;
return in;
}
};
Used like
uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");
That way you don't need one impl per int type.
Working example with strtoul will be:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "fffefffe";
char * p;
long n = strtoul( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
strtol converts string to long. On my computer numeric_limits<long>::max() gives 0x7fffffff. Obviously that 0xfffefffe is greater than 0x7fffffff. So strtol returns MAX_LONG instead of wanted value. strtoul converts string to unsigned long that's why no overflow in this case.
Ok, strtol is considering input string not as 32-bit signed integer before convertation. Funny sample with strtol:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "-0x10002";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
The code above prints -65538 in console.
Here's a simple and working method I found elsewhere:
string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);
Please note that you might prefer using unsigned long integer/long integer, to receive the value.
Another note, the c_str() function just converts the std::string to const char* .
So if you have a const char* ready, just go ahead with using that variable name directly, as shown below [I am also showing the usage of the unsigned long variable for a larger hex number. Do not confuse it with the case of having const char* instead of string]:
const char *hexString = "7FFEA5"; //Just to show the conversion of a bigger hex number
unsigned long hexNumber; //In case your hex number is going to be sufficiently big.
sscanf(hexString, "%x", &hexNumber);
This works just perfectly fine (provided you use appropriate data types per your need).
I had the same problem today, here's how I solved it so I could keep lexical_cast<>
typedef unsigned int uint32;
typedef signed int int32;
class uint32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator uint32() const { return value; }
friend std::istream& operator>>( std::istream& in, uint32_from_hex& outValue )
{
in >> std::hex >> outValue.value;
}
};
class int32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator int32() const { return static_cast<int32>( value ); }
friend std::istream& operator>>( std::istream& in, int32_from_hex& outValue )
{
in >> std::hex >> outvalue.value;
}
};
uint32 material0 = lexical_cast<uint32_from_hex>( "0x4ad" );
uint32 material1 = lexical_cast<uint32_from_hex>( "4ad" );
uint32 material2 = lexical_cast<uint32>( "1197" );
int32 materialX = lexical_cast<int32_from_hex>( "0xfffefffe" );
int32 materialY = lexical_cast<int32_from_hex>( "fffefffe" );
// etc...
(Found this page when I was looking for a less sucky way :-)
Cheers,
A.
just use stoi/stol/stoll
for example:
std::cout << std::stol("fffefffe", nullptr, 16) << std::endl;
output: 4294901758
This worked for me:
string string_test = "80123456";
unsigned long x;
signed long val;
std::stringstream ss;
ss << std::hex << string_test;
ss >> x;
// ss >> val; // if I try this val = 0
val = (signed long)x; // However, if I cast the unsigned result I get val = 0x80123456
Try this. This solution is a bit risky. There are no checks. The string must only have hex values and the string length must match the return type size. But no need for extra headers.
char hextob(char ch)
{
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
return 0;
}
template<typename T>
T hextot(char* hex)
{
T value = 0;
for (size_t i = 0; i < sizeof(T)*2; ++i)
value |= hextob(hex[i]) << (8*sizeof(T)-4*(i+1));
return value;
};
Usage:
int main()
{
char str[4] = {'f','f','f','f'};
std::cout << hextot<int16_t>(str) << "\n";
}
Note: the length of the string must be divisible by 2
For those looking to convert number base for unsigned numbers, it is pretty trivial to do yourself in both C/C++ with minimal dependency (only operator not provided by the language itself is pow() function).
In mathematical terms, a positive ordinal number d in base b with n number of digits can be converted to base 10 using:
Example: Converting base 16 number 00f looks like:
= 0*16^2 + 0*16^1 + 16*16^0 = 15
C/C++ Example:
#include <math.h>
unsigned int to_base10(char *d_str, int len, int base)
{
if (len < 1) {
return 0;
}
char d = d_str[0];
// chars 0-9 = 48-57, chars a-f = 97-102
int val = (d > 57) ? d - ('a' - 10) : d - '0';
int result = val * pow(base, (len - 1));
d_str++; // increment pointer
return result + to_base10(d_str, len - 1, base);
}
int main(int argc, char const *argv[])
{
char n[] = "00f"; // base 16 number of len = 3
printf("%d\n", to_base10(n, 3, 16));
}
tl;dr
Why do I get different output every time I run this code (Ideone):
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
const char* _user = "FOO";
const char* _password = "BAR";
char login[21];
sprintf(login,
"\x15\x00\x01%-8s%-10s",
_user,
_password);
for (int i = 0; i < 21; i++) {
printf(" %02x", login[i] & 0xff);
}
return 0;
}
But not this code (Ideone):
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
const char* _user = "FOO";
const char* _password = "BAR";
const char* _session = "ABCDEFGHIJ";
int _expectedSeq = 123;
char login[38];
sprintf(login,
"L%-6s%-10s%10s%10d\xA",
_user,
_password,
_session,
_expectedSeq);
for (int i = 0; i < 38; i++) {
printf(" %02x", login[i] & 0xff);
}
return 0;
}
Question
Deep in our application code, I came across this:
char login[38];
sprintf(login,
"L%-6s%-10s%10s%10d\xA",
_user,
_password,
_session,
_expectedSeq);
Now, I need to write a (simpler) variant of this code:
char login[21];
sprintf(login,
"\x15\x00\x01%-8s%-10s",
_user,
_password);
Somehow, this doesn't work! What's weird is that the latter produces different results every time.
Thoughts
The former example only has a hex literal at the end. Is this masking the issue in the former's case?
Or, am I actually messing up my debug output, printf? (By the way, I got the & 0xff thing from Printing hexadecimal characters in C.)
Could it have something to do with using char instead of unsigned char? But then, why does the former case work?
The problem is that your string literal has an embedded NUL byte, and that marks the end of the string as far as sprintf is concerned. So your call is identical to:
sprintf(login,
"\x15",
_user,
_password);
And that writes into the login array only two bytes: 0x15 0x00.
There are several approaches to solve this mixing of bytes and characters. My choice would be something along the lines of:
memcpy(login, "\x15\x00\x01", 3);
sprintf(login + 3,
"%-8s%-10s",
_user,
_password);
The call to memcpy takes as parameter the number of bytes, so it is immune to the embedded NUL problem.
But note that sprintf automaticall adds a NUL byte at the end of the output string, so you actually need 22 bytes: 3 + 8 + 10 + 1 = 22:
char login[22];
Your issue is that second format string contains a null character (\x00) which terminates it prematurely. Change the string to use %c instead and have a null character printed there.
Is there anyway , if I enter any string , then I want to scan ASCII value of each character inside that string , if I enter "john" then I should get 4 variables getting ASCII value of each character, in C or C++
Given a string in C:
char s[] = "john";
or in C++:
std::string s = "john";
s[0] gives the numeric value of the first character, s[1] the second an so on.
If your computer uses an ASCII representation of characters (which it does, unless it's something very unusual), then these values are the ASCII codes. You can display these values numerically:
printf("%d", s[0]); // in C
std::cout << static_cast<int>(s[0]); // in C++
Being an integer type (char), you can also assign these values to variables and perform arithmetic on them, if that's what you want.
I'm not quite sure what you mean by "scan". If you're asking how to iterate over the string to process each character in turn, then in C it's:
for (char const * p = s; *p; ++p) {
// Do something with the character value *p
}
and in (modern) C++:
for (char c : s) {
// Do something with the character value c
}
If you're asking how to read the string as a line of input from the terminal, then in C it's
char s[SOME_SIZE_YOU_HOPE_IS_LARGE_ENOUGH];
fgets(s, sizeof s, stdin);
and in C++ it's
std::string s;
std::cin >> s; // if you want a single word
std::getline(std::cin, s); // if you want a whole line
If you mean something else by "scan", then please clarify.
You can simply get the ascii value of a char by casting it to type int:
char c = 'b';
int i = c; //i contains ascii value of char 'b'
Thus, in your example the code to get the ascii values of a string would look something like this:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string text = "John";
for (int i = 0; i < text.size(); i++)
{
cout << (int)text[i] << endl; //prints corresponding ascii values (one per line)
}
}
To get the corresponding char from an integer representing an entry in the ascii table, you just have to cast the int back to char again:
char c = (char)74 // c contains 'J'
The code given above was written in C++ but it basically works the same way in C (and many other languages as well I guess)
There is no way to turn a string of length 'x' into x variables. In C or C++ you can only declare a fixed number of variables. But probably you don't need to do what you are saying. Perhaps you just need an array, or most likely you just need a better way to solve whatever problem you are trying to solve. If you explain what the problem is in the first place, then I'm sure a better way can be explained.
Ya,I think there are some more better solutions are also available but this one also be helpful.
In C
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(){
char s[]="abc";
int cnt=0;
while(1){
if(s[cnt++]==NULL)break;
}
int *a=(int *)malloc(sizeof(int)*cnt);
for(int i=0;i<cnt;i++)a[i]=s[i];
for(int i=0;i<cnt-1;i++)printf("%d\n",a[i]);
return 0;
}
In C++
#include <iostream>
#include <string>
using namespace std;
int main(){
string s="abc";
//int *a=new int[s.length()];
//for(int i=0;i<s.length();i++)a[i]=s[i];
for(int i=0;i<s.length();i++)
cout<<(int)s[i]<<endl;
return 0;
}
I hope this one will be helpful..
yeah it's very easy ..just a demo
int main()
{
char *s="hello";
while(*s!='\0')
{
printf("%c --> %d\n",*s,*s);
s++;
}
return 0;
}
But make sure your machine is supporting the ASCII value format.
In C every char has one integral value associted with it called ASCII.
Using %d format specifier you can directly print the ASCII of any char as above.
NOTE: It's better to get good book and practice this kind of program yourself.