Converting integer to string in c++ - c++

This is the code I wrote to convert integer to string.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)b);
cout<<s<<endl;
}
I expected the output to be 5 but it is giving me blank space.
I know there is another way of doing it using stringstream but I want to know what is wrong in this method?

Character code for numbers are not equal to the integer the character represents in typical system.
It is granteed that character codes for decimal digits are consecutive (N3337 2.3 Character sets, Paragraph 3), so you can add '0' to convert one-digit number to character.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)(b + '0'));
cout<<s<<endl;
}

You are interpreting the integer 5 as a character. In ASCII encoding, 5 is the Enquiry control character as you lookup here.
The character 5 on the other hand is represented by the decimal number 53.

As others said, you can't convert an integer to a string the way you are doing it.
IMHO, the best way to do it is using the C++11 method std::to_string.
Your example would translate to:
using namespace std;
int main()
{
string s;
int b=5;
s = to_string(b);
cout<<s<<endl;
}

The problem in your code is that you are converting the integer 5 to ASCII (=> ENQ ASCII code, which is not "printable").
To convert it to ASCII properly, you have to add the ASCII code of '0' (48), so:
char ascii = b + '0';
However, to convert an integer to std::string use:
std::stringstream ss; //from <sstream>
ss << 5;
std::string s = ss.str ();
I always use this helper function in my projects:
template <typename T>
std::string toString (T arg)
{
std::stringstream ss;
ss << arg;
return ss.str ();
}

Also, you can use stringstream,
std::to_string doesn't work for me on GCC

If we were writing C++ from scratch in 2016, maybe we would make this work. However as it choose to be (mostly) backward compatible with a fairly low level language like C, 'char' is in fact just a number, that string/printing algorithms interpret as a character -but most of the language doesn't treat special. Including the cast. So by doing (char) you're only converting a 32 bit signed number (int) to a 8 bit signed number (char).
Then you interpret it as a character when you print it, since printing functions do treat it special. But the value it gets printed to is not '5'. The correspondence is conventional and completely arbitrary; the first numbers were reserved to special codes which are probably obsolete by now. As Hoffman pointed out, the bit value 5 is the code for Enquiry (whatever it means), while to print '5' the character has to contain the value 53. To print a proper space you'd need to enter 32. It has no meaning other than someone decided this was as good as anything, sometime decades ago, and the convention stuck.
If you need to know for other characters and values, what you need is an "ASCII table". Just google it, you'll find plenty.
You'll notice that numbers and letters of the same case are next to each other in the order you expect, so there is some logic to it at least. Beware, however, it's often not intuitive anyway: uppercase letters are before lowercase ones for instance, so 'A' < 'a'.
I guess you're starting to see why it's better to rely on dedicated system functions for strings!

Related

C++ Atoi can't handle special characters

Im using this atoi to remove all letters from the string. But my string uses special characters as seen below, because of this my atoi exits with an error. What should I do to solve this?
#include <iostream>
#include <string>
using namespace std;
int main() {
std::string playerPickS = "Klöver 12"; // string with special characters
size_t i = 0;
for (; i < playerPickS.length(); i++) { if (isdigit(playerPickS[i])) break; }
playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
cout << atoi(playerPickS.c_str());
}
This is what I believe is the error. I only get this when using those special characters, thats why I think thats my problem.
char can be signed or unsigned, but isidigt without a locale overload expects a positive number (or EOF==-1). In your encoding 'ö' has a negative value. You can cast it to unsigned char first: is_digit(static_cast<unsigned char>(playerPickS[i])) or use the locale-aware variant.
atoi stops scanning when it finds something that's not a digit (roughly speaking). So, to get it to do what you want, you have to feed it something that at least starts with the string you want to convert.
From the documentation:
[atoi] Discards any whitespace characters until the first non-whitespace character is found, then takes as many characters as possible to form a valid integer number representation and converts them to an integer value. The valid integer value consists of the following parts:
(optional) plus or minus sign
numeric digits
So, now you know how atoi works, you can pre-process your string appropriately before passing it in. Good luck!
Edit: If your call to isdigit is failing to yield the desired result, the clue lies here:
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
So you need to check for that yourself before you call it. Casting playerPickS[i] to an unsigned int will probably work.

Why is strlen(s) different from the size of s, and why does cout char display a character not a number?

I wrote a piece of code to count how many 'e' characters are in a bunch of words.
For example, if I type "I read the news", the counter for how many e's are present should be 3.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s[255],n,i,nr=0;
cin.getline(s,255);
for(i=1; i<=strlen(s); i++)
{
if(s[i-1]=='e') nr++;
}
cout<<nr;
return 0;
}
I have 2 unclear things about characters in C++:
In the code above, if I replace strlen(s) with 255, my code just doesn't work. I can only type a word and the program stops. I have been taught at school that strlen(s) is the length for the string s, which in this case, as I declared it, is 255. So, why can't I just type 255, instead of strlen(s)?
If I run the program above normally, it doesn't show me a number, like it is supposed to do. It shows me a character (I believe it is from the ASCII table, but I'm not sure), like a heart or a diamond. It is supposed to print the number of e's from the words.
Can anybody please explain these to me?
strlen(s) gives you the length of the string held in the s variable, up to the first NULL character. So if you input "hello", the length will be 5, even though s has a capacity of 255....
nr is displayed as a character because it's declared as a char. Either declare it as int, for example, or cast it to int when cout'ing, and you'll see a number.
strlen() counts the actual length of strings - the number of real characters up to the first \0 character (marking end of string).
So, if you input "Hello":
sizeof(s) == 255
strlen(s) == 5
For second question, you declare your nr as char type. std::cout recognizes char as a single letter and tries it print it as such. Declare your variable as int type or cast it before printing to avoid this.
int nr = 42;
std::cout << nr;
//or
char charNr = 42;
std::cout << static_cast<int>(charNr);
Additional mistakes not mentioned by others, and notes:
You should always check whether the stream operation was successful before trying to use the result.
i is declared as char and cannot hold values greater than 127 on common platforms. In general, the maximum value for char can be obtained as either CHAR_MAX or std::numeric_limits<char>::max(). So, on common platforms, i <= 255 will always be true because 255 is greater than CHAR_MAX. Incrementing i once it has reached CHAR_MAX, however, is undefined behavior and should never be done. I recommend declaring i at least as int (which is guaranteed to have sufficient range for this particular use case). If you want to be on the safe side, use something like std::ptrdiff_t (add #include <cstddef> at the start of your program), which is guaranteed to be large enough to hold any valid array size.
n is declared but never used. This by itself is harmless but may indicate a design issue. It can also lead to mistakes such as trying to use n instead of nr.
You probably want to output a newline ('\n') at the end, as your program's output may look odd otherwise.
Also note that calling a potentially expensive function such as strlen repeatedly (as in the loop condition) can have negative performance implications (strlen is typically an intrinsic function, though, and the compiler may be able to optimize most calls away).
You do not need strlen anyway, and can use cin.gcount() instead.
Nothing wrong with return 0; except that it is redundant – this is a special case that only applies to the main function.
Here's an improved version of your program, without trying to change your code style overly much:
#include <iostream>
#include <cstring>
#include <cstddef>
using namespace std;
int main()
{
char s[255];
int nr=0;
if ( cin.getline(s,255) )
{ // only if reading was successful
for(int i=0; i<cin.gcount(); i++)
{
if(s[i]=='e') nr++;
}
cout<<nr<<'\n';
}
return 0;
}
For exposition, the following is a more concise and expressive version using std::string (for arbitrary length input), and a standard algorithm. (As an interviewer, I would set this, modulo minor stylistic differences, as the canonical answer i.e. worth full credit.)
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
if ( getline(cin, s) )
{
cout << std::count(begin(s), end(s), 'e') << '\n';
}
}
I have 2 unclear things about characters in C++: 1) In the code above,
if I replace the "strlen(s)" with 255, my code just doesn't work, I
can only type a word and the program stops, and I have been taught at
school that "strlen(s)" is the length for the string s, wich in this
case, as I declared it, is 255. So, why can't I just type 255, instead
of strlen(s);
That's right, but strings only go the null terminator, even if there's more space allocated. Consider this, per example:
char buf[32];
strcpy(buf, "Hello World!");
There's 32 chars worth of space, but my string is only 12 characters long. That's why strlen returns 12 in this example. It's because it doesn't know how long the buffer is, it only knows the address of the string and parses it until it finds the null terminator.
So if you enter 255, you're going past what was set by cin and you'll read the rest of the buffer. Which, in this case, is uninitialized. That's undefined behavior - in this case it will most likely read some rubbish values, and those might coincidentally have the 'e' value and thus give you a wrong result.
2) If you run the program above normaly, it doesn't show you a number,
like it's supposed to do, it shows me a character(I believe it's from
the ASCII table but I'm not sure), like a heart or a diamond, but it
is supposed to print the number of e's from the words. So can anybody
please explain these to me?
You declared nr as char. While that can indeed hold an integer value, if you print it like this, it will be printed as a character. Declare it as int instead or cast it when you print it.

C++ convert UTF8 string to hexadecimal and vice versa

It took time looking as utf8 convert string to hexadecimal string, and backwards
I found some examples and possible solutions, but all work well only without special characters.
I have a folowing :
string in="áéíóúñü"
The result shoud be:
"c3a1c3a9c3adc3b3c3bac3b1c3bc"
I try following post, and others:
C++ convert string to hexadecimal and vice versa
How to convert a string in hexadecimal string?
http://www.cplusplus.com/forum/beginner/161703/
I will try to explain better, but I can not speak English properly. Sorry.
I have to send some data using socket. For that I have to convert names to hexadecimal using UTF-8, but in some cases have specials characters for example á, é, í...
When converting normal letters get a string length of 2 per letter.
a-> "61"
e-> "65"
But special characters are encoded (on UTF-8) with length 4
á-> "c3a1" this is the correct conversion
é-> "c3a9" this is the correct conversion
I have attempted the conversion of all the ways I've found, including that suggested me down. But every time you convert a special character gives me an answer of 2 digits, that is not correct.
á-> "e1" this isnt correct
é-> "e9" this isnt correct
Loop over each "character" in the std::string object, output it's two-digit hexadecimal equivalent as an int.
For looping, I recommend you look into range-based for loops.
To set the number of digits to print, read about setting stream precision.
To print a number as hexadecimal, read about the base I/O manipulators.
To convert to an int read about static_cast.
Oh, and I recommend using an unsigned char for the single "characters".
Simple solution based on the above:
std::string stoh(std::string const& in)
{
std::ostringstream os;
for(unsigned char const& c : in)
{
os << std::hex << std::setprecision(2) << std::setw(2)
<< std::setfill('0') << static_cast<int>(c);
}
return os.str();
}

Convert a single character to lowercase in C++ - tolower is returning an integer

I'm trying to convert a string to lowercase, and am treating it as a char* and iterating through each index. The problem is that the tolower function I read about online is not actually converting a char to lowercase: it's taking char as input and returning an integer.
cout << tolower('T') << endl;
prints 116 to the console when it should be printing T.
Is there a better way for me to convert a string to lowercase?
I've looked around online, and most sources say to "use tolower and iterate through the char array", which doesn't seem to be working for me.
So my two questions are:
What am I doing wrong with the tolower function that's making it return 116 instead of 't' when I call tolower('T')
Are there better ways to convert a string to lowercase in C++ other than using tolower on each individual character?
That's because there are two different tolower functions. The one that you're using is this one, which returns an int. That's why it's printing 116. That's the ASCII value of 't'. If you want to print a char, you can just cast it back to a char.
Alternatively, you could use this one, which actually returns the type you would expect it to return:
std::cout << std::tolower('T', std::locale()); // prints t
In response to your second question:
Are there better ways to convert a string to lowercase in C++ other than using tolower on each individual character?
Nope.
116 is indeed the correct value, however this is simply an issue of how std::cout handles integers, use char(tolower(c)) to achieve your desired results
std::cout << char(tolower('T')); // print it like this
It's even weirder than that - it takes an int and returns an int. See http://en.cppreference.com/w/cpp/string/byte/tolower.
You need to ensure the value you pass it is representable as an unsigned char - no negative values allowed, even if char is signed.
So you might end up with something like this:
char c = static_cast<char>(tolower(static_cast<unsigned char>('T')));
Ugly isn't it? But in any case converting one character at a time is very limiting. Try converting 'ß' to upper case, for example.
To lower is int so it returns int. If you check #include <ctype> you will see that definition is int tolower ( int c ); You can use loop to go trough string and to change every single char to lowe case. For example
while (str[i]) // going trough string
{
c=str[i]; // ging c value of current char in string
putchar (tolower(c)); // changing to lower case
i++; //incrementing
}
the documentation of int to_lower(int ch) mandates that ch must either be representable as an unsigned char or must be equal to EOF (which is usually -1, but don't rely on that).
It's not uncommon for character manipulation functions that have been inherited from the c standard library to work in terms of ints. There are two reasons for this:
In the early days of C, all arguments were promoted to int (function prototypes did not exist).
For consistency these functions need to handle the EOF case, which for obvious reasons cannot be a value representable by a char, since that would mean we'd have to lose one of the legitimate encodings for a character.
http://en.cppreference.com/w/cpp/string/byte/tolower
The answer is to cast the result to a char before printing.
e.g.:
std::cout << static_cast<char>(std::to_lower('A'));
Generally speaking to convert an uppercase character to a lowercase, you only need to add 32 to the uppercase character as this number is the ASCII code difference between lowercase and uppercase characters, e.g., 'a'-'A'=97-67=32.
char c = 'B';
c += 32; // c is now 'b'
printf("c=%c\n", c);
Another easy way would be to first map the uppercase character to an offset within the range of English alphabets 0-25 i.e. 'a' is index '0' and 'z' is index '25' inclusive and then remap it to a lowercase character.
char c = 'B';
c = c - 'A' + 'a'; // c is now 'b'
printf("c=%c\n", c);

Char to Int in C++? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to convert a single char into an int
Well, I'm doing a basic program, wich handles some input like:
2+2
So, I need to add 2 + 2.
I did something like:
string mys "2+2";
fir = mys[0];
sec = mys[2];
But now I want to add "fir" to "sec", so I need to convert them to Int.
I tried "int(fir)" but didn't worked.
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
Alright so first a little backround on why what you attempted didn't work. In your example, fir is declared as a string. When you attempted to do int(fir), which is the same as (int)fir, you attempted a c-style cast from a string to an integer. Essentially you will get garbage because a c-style cast in c++ will run through all of the available casts and take the first one that works. At best your going to get the memory value that represents the character 2, which is dependent upon the character encoding your using (UTF-8, ascii etc...). For instance, if fir contained "2", then you might possibly get 0x32 as your integer value (assuming ascii). You should really never use c-style casts, and the only place where it's really safe to use them are conversions between numeric types.
If your given a string like the one in your example, first you should separate the string into the relevant sequences of characters (tokens) using a function like strtok. In this simple example that would be "2", "+" and "2". Once you've done that you can simple call a function such as atoi on the strings you want converted to integers.
Example:
string str = "2";
int i = atoi(str.c_str()); //value of 2
However, this will get slightly more complicated if you want to be able to handle non-integer numbers as well. In that case, your best bet is to separate on the operand (+ - / * etc), and then do a find on the numeric strings for a decimal point. If you find one you can treat it as a double and use the function atof instead of atoi, and if you don't, just stick with atoi.
Have you tried atoi or boost lexical cast?