I have a string a = "Hello world!", now for fun I wish to change the first letter in the string a to a number of my choosing. for example
string a = "Hello world!";
int x;
std:cin>>x;
a[0] = x;
cout << a;
Now what i want it to produce is "xello world!" x being the number i typed in, but instead I get a little smiley face.
Anyone seen anything similar and know how to fix it?
Also: Why can you even access a string like this string[] ? it's not a char array o.o
If x is a single digit number, do this instead:
a[0] = x + '0';
EDIT:
Why this works:
Each element in string is a char. A char is represented by an integer. You can check this up in the ASCII table. For example, integer 48 represents char '0', integer 49 represents char '1', etc. Thus, by adding your integer x to char '0', you can get the digit 'x' that you want.
Why it might be dangerous:
One reason that I could think of would be when writing to unallocated memory in an empty string, which might invoke undefined behavior.
You can then check if a string is empty with string::empty(). In this case,
if (!a.empty()) {...}
Using string::replace and std::to_string, this will work regardless if x is a single or multiple digit number:
string a = "Hello world!";
int x;
std:cin>>x;
a.replace(0, 1, std::to_string(x));
Live Example
As an additional answer you could use the at() method in a try block as it is performing bounds checking and throws exception of type std::out_of_range if the access is invalid:
If you add x + '0' and x is higher than 9 it won't give you a number.Look at the ascii table
int main()
{
std::string a { "Hello World" };
int x {};
std::cin >> x;
try {
a.at(0) = '0' + x; // OOPS: '0' + 10 will give you ':'
std::cout << a << '\n';
}
catch(std::out_of_range& e) {
std::cout << e.what();
}
}
A better solution is what #PaulMcKenzie answered, to use std::to_string and string::replace.
Related
I am trying to understand the difference between the '<<' operator and the 'put()' function for writing characters to an output file.
My code:
#include <fstream>
using namespace std;
int main() {
ofstream out ("output.txt");
int x = 1;
// This produces the incorrect result ...
out.put(x);
// ... while this produces the correct result
out << x;
// These two produce the same (correct) result
out.put('a');
out << 'a';
out.close;
}
I get that out.put(x) converts the integer 1 into a character according ASCII code, but I don't understand why this doesn't happen when I use out << x.
However, out.put('a') does produce the same as out << 'a'.
Why is this?
int x = 1;
// This produces the incorrect result ...
out.put(x);
No, it converts the int to a char and outputs one char, with the value 1.
// ... while this produces the correct result
out << x;
That does formatted output and outputs the the representation of the value x holds. Most probably it'll show the character 1 which is different from the character with value 1.
// These two produce the same (correct) result
out.put('a');
out << 'a';
Yes, there's no conversion there. Had you done
int x = 'A';
out.put(x);
out << x;
You'd probably see A65 where A comes from the put(x) and 65 from the formatted output since 65 is often the value of 'A'.
When you use out << 1, you call: operator<<(int val) and not: operator<<(char val), then he can cast int to std::string.
I'm a beginner to C++ so forgive me if I'm making a stupid mistake here.
I want to loop through a string of integers in the following code:
#include <string>
using namespace std;
int main() {
string str = "12345";
for (int i : str) {
cout << i << endl;
}
return 0;
}
But I receive the output:
49
50
51
52
53
I know that I get normal output if I use char instead of int, but why do I receive an output of integers 48 more than they should be?
When you loop through a string you get elements of type char. If you convert a char to an int you get the ASCII value of the char, which is what happens when you do:
string str = "12345";
for (int i : str) { // each char is explicitly converted to int
cout << i << endl; // prints the ascii value
}
The ASCII value of '0' is 48, and '1' is 49, etc, which explains the output you get.
Just what #cigien said, You just need to change it from int to char i.e
string str = "12345";
for (char i : str) {
cout << i << endl;
}
Or one solution for all auto keyword
string str = "12345";
for (auto i : str) {
cout << i << endl;
}
The first thing you need to know is that a string is an array/sequence of chars.
You can think of a char as a single character.
But the way it is encoded is as a number.
For example, the char 'a' is encoded (in ASCII) as the number 97.
Now your for loop says int i: str.
You're telling it to look for integers in the string.
But a string is an array/sequence of chars, not of integers.
So the loop takes each char,
and instead of looking at what the character itself is,
it gives you the integer encoding value of the char,
the ASCII value.
Now the numbers are encoded with the char '0' having the lowest encoding value,
'1' having the next value,
'2', having the next,
and so on through digit '9'.
I can never remember what the actual ASCII value for '0' is . . . .
But because the digit chars are encoded consecutively in this way,
you can convert any digit char to its int value by subtracting the underlying integer encoding value of '0'.
#include <string>
using namespace std;
int main() {
string str = "12345";
for (char c: str) {
cout << (c - '0') << endl; // gives you the actual int value, but only works if the char is actually a digit
}
return 0;
}
for (int i : str) { is infact syntactic sugar for
for (auto iterator = str.begin(); iterator != str.end(); iterator++) {
int i = (int) *iterator;
But the *-operator from string::iterator is infact an overload which returns the current char. It will as such be casted to an int. What you then see is this number. It is the integer value of the byte. Not necessarily ASCII. It could be ANSI too.
int main() {
vector<string> tab;
tab.push_back("1234");
cout << tab[0][0];// -> 1
if (int(tab[0][0]) == 1) {
cout << "test";
}
}
why does this comparison not work? what am I doing wrong?
'1' the character is not the same as 1 the integer.
To do your comparison write
if (tab[0][0] == '1') {
Specifically when you convert a character to an integer what you get is the encoding of the character. If you are using ASCII (which is very likely) then the encoding of '1' is 49.
You're confusing numbers (1, 2, 3, ...) and digits ('1', '2', '3', ...).
They look the same when you print them, but they are not the same.
The expression tab[0][0] will evaluate to the first character of the first string in the tab vector. Note that this is a character representation (probably ASCII, but not necessarily so), which will not have the numerical value of 1 (it will have the value 49 if your system uses ASCII).
So, in your if test, you need to compare the value with a character literal rather than an integer literal, like so:
int main() {
vector<std::string> tab;
tab.push_back("1234");
std::cout << tab[0][0];// -> 1
if (int(tab[0][0]) == '1') { // Compare to the character '1'!
std::cout << "test";
}
}
If You Want To Convert A String To A Number Use The Function Atoi()
std::string str = "12345";
int num = std::atoi(str.c_str());
// num = 12345
If You Want one Single Character Not a char*
std::string str = "12345";
int num = str[0] - '0';
// num = 1
I'm trying to keep the alphabet in a char array. But 4 letters show absurd charachters.
I run the program step by step using F11 button. Wrote the alphabet and after 'Q', until 'V' whatever I write, it shows ...PQÿÿÿÿVWXYZ this character: 'ÿ'
int main()
{
cout << "ALPHABET:";
char alf[] = "";
cin >> alf;
system("PAUSE");
}
I expect: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Actual result: ABCDEFGHIJKLMNOPQÿÿÿÿVWXYZ
Problem is with this line:
char alf[] = "";
you declare char array with size 1 which can only hold empty strings (null terminator). Note that std::istream::operator>> with char * does not validate size of array (it cannot) so you are getting Undefined Behavior writing into array with out of bounds. Solution is to use std::string instead which will grow as needed.
int main()
{
std::cout << "ALPHABET:";
std::string alf;
std::cin >> alf;
std::cout << alf << std::endl;
}
int main()
{
char hmm[1000];
cin.getline(hmm, 1000);
cout << hmm << endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '#'; sayac++) {
if (!isdigit(hmm[sayac])) {
if (islower(hmm[sayac]))
cout << toupper(hmm[sayac]);
else if (isupper(hmm[sayac]))
cout << tolower(hmm[sayac]);
else
cout << hmm[sayac];
}
}
"Write a program that reads keyboard input to the # symbol and that echoes the input
except for digits, converting each uppercase character to lowercase, and vice versa.
(Don’t forget the cctype family.) "
I'm doing this exercise from the primer book. But when I run it, it returns the ascii order of the char, not the uppercase/lowercase version of the character. Couldn't figure out the problem. Can someone tell my why please?
(I may have other problems about the exercise, please don't correct them if I have. I want to fix it on my own (except the problem I explained), but I can't check the other ones as I have this problem.
When writing
std::cout << toupper('a');
the following happen:
int toupper(int ch) is called, and returns an integer whose value is 'A' (0x41).
std::basic_ostream::operator<<(std::cout, 0x41) is called, that is the int (2) overload since an int was provided.
Overall, it prints "65".
As a solution, you can cast back your upper case to a char:
std::cout << static_cast<char>(toupper('a'));
It's a question of representation. There is no difference between a character and that character's numeric value. It's all in how you choose to display it. For example, the character 'a' is just a constant with a value equal to the character's numeric value.
The problem you are having is that std::toupper and std::tolower return an int rather than a char. One reason for that is that they handle EOF values, which are not necessarily representable by char. As a consequence, std::cout see you are trying to print an int and not a char. The standard behavior for streaming an int is to print the number. The solution is then to cast your result to char to force the value to be interpreted as a character. You can use something like std::cout << static_cast<char>(std::toupper(hmm[sayac]));.
Try the following :
#include <cctype>
#include <iostream>
int main()
{
char hmm[1000];
std::cin.getline(hmm, 1000);
std::cout << hmm << std::endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '#'; sayac++) {
if (!std::isdigit(hmm[sayac])) {
if (std::islower(hmm[sayac]))
std::cout << static_cast<char>(std::toupper(hmm[sayac]));
else if (isupper(hmm[sayac]))
std::cout << static_cast<char>(std::tolower(hmm[sayac]));
else
std::cout << hmm[sayac];
}
}
}
You should also consider using an std::string instead of an array of char of arbitrary length. Also, take note that you have undefined behavior if the input string does not contain #.