Difference between '<<' and 'put()' for output filestreams - c++

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.

Related

wstring decreasing by one character every time it is printed c++ [duplicate]

When i try to add text to string i get random values.
Code:
#include <iostream>
using namespace std;
int main()
{
cout << "333" + 4;
}
I get some random text like:↑←#
"333" is a const char [4] not std::string as you might expect(which by the way still doesn't have operator+ for int). Adding 4, you're converting it to const char * and then moving the pointer by 4 * sizeof(char) bytes, making it point to memory with garbage in it.
It happens because those are two different types and the adding operator does not work as you may expect.
If you intend to concatenate the string literals "333" with the int value of 4 than you should simply use count like:
cout << "333" << 4; // outputs: 3334
If you want to display the sum, than use string to int conversion with the stoi() function.
cout << stoi("333") + 4; // outputs: 337
Note: When using stoi(): If the string also contains literals, than the conversion will take the integer value from the beginning of the string or will raise an error in case the string begins with literals:
cout << stoi("333ab3") + 4; // same as 333 + 4, ignoring the rest, starting a
cout << stoi("aa333aa3") + 4; // raise error as "aa" can't be casted to int
As you want to add text to text, solution would be to use proper types:
cout << std::string( "333" ) + "4";
or for c++14 or later:
using namespace std::string_literals;
cout << "333"s + "4"s;
I honestly do not know what you are trying to achieve by adding int to string. In case you want to add 333+4, you need to Parse string in to int like this :
edit:Typo
#include
using namespace std;
int main()
{
cout << std::stoi("333") + 4;
}

Concatenating char variables

I tried making a small program using the libraries "iostream" and "String" to display a given string backwardly as the output on the command prompt. I used a recursive returning-value (string) function to perform the whole process of getting the given string in backward and returning it to the main function to be displayed on screen, as you can see below:
#include <iostream>
#include <string>
using namespace std;
string rev(string, int);
int main() {
string let;
cout << "Enter your string: ";
cin >> let;
cout << "The string in reverse is: " << rev(let, let.length());
cout << endl;
return 0;
}
string rev(string x, int y) {
if (y != 0 )
return x[y - 1] + rev(x, y - 1);
else
return "\0";
}
What I don't get about the process, is that while the concatenation performed on the rev function, recursively, and with the char variables works correctly and returns the string in backward to the main function, trying to concatenate the char variables normally like this gives rubbish as the output:
#include <iostream>
#include <string>
using namespace std;
int main() {
string hd;
string ah = "foo";
hd = ah[2] + ah[1] + ah[0];
cout << hd << endl;
return 0;
}
And even if I add to the "hd" chain "\0", it still gives rubbish.
Your first example implicitly converts characters to strings and uses appropriate operator +
While your second example is adding up characters
https://en.cppreference.com/w/cpp/string/basic_string/operator_at
returns reference to character at position
Writing instead
hd = ""s + ah[2] + ah[1] + ah[0];
will, informally speaking, put + into a "concatenation mode", achieving what you want. ""s is a C++14 user-defined literal of type std::string, and that tells the compiler to use the overloaded + operator on the std::string class on subsequent terms in the expression. (An overloaded + operator is also called in the first example you present.)
Otherwise, ah[2] + ah[1] + ah[0] is an arithmetic sum over char values (each one converted to an int due to implicit conversion rules), with the potential hazard of signed overflow on assignment to hd.
How about making use of everything that's already available?
string rev(const string &x) { return string{x.rbegin(), x.rend()}; }
Reverse iterators allow you to reverse the string, and the constructor of string with 2 iterators, constructs an element by iterati from begin to end.

ASCII to dec stored in string

The string str_hex contains the hex-values for the letters A-J, which corresponds to the decimal values 65-74. I'm trying to cast each hex-value to its decimal value following this example. It works nice for the std::cout case inside the for-loop, but the output-std::string still has the ascii-values. Why does this not work or is there a nicer/more proper way to build my output string?
#include <string>
#include <iostream>
#include <stdint.h>
int main()
{
std::string str_hex("\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b", 10);
std::string str_output = "";
for (int i = 0; i < 10; ++i)
{
uint8_t tmp = str_hex[i];
str_output.append(1, (unsigned)tmp);
std::cout << "cout+for: " << (unsigned)tmp << std::endl;
if(i<9)
str_output.append(1, '-');
}
std::cout << std::endl << "cout+str_append: " << str_output << std::endl;
return 0;
}
Compiling and running the program gives the following output:
cout+for: 65
cout+for: 66
cout+for: 67
...
cout+str_append: A-B-C-D-E-F-G-H-I-J
The desired output is:
cout+str_append: 65-66-67-68-...
The method string::append accepts, among the various overload, a size_t and a char, see reference.
string& append (size_t n, char c);
Therefore, in your code line
str_output.append(1, (unsigned)tmp);
you are implicitly converting the unsigned tmp to a char, i.e., to a single letter. To obtain the output you want, you have to convert tmp to a string containing the number, and then append it to str_output. You can do that by using
str_output+=std::to_string(tmp);
instead of str_output.append(1, (unsigned)tmp);.
You have to change your string append to for the change from a number to its "string":
str_output.append(std::to_string(tmp));
It's not one character that you want to add, but a string representing the number.

Changing the character inside a string to number

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.

How to output the Binary value of a variable in C++

I've got a homework assignment in my C++ programming class to write a function that outputs the binary value of a variable's value.
So for example, if I set a value of "a" to a char I should get the binary value of "a" output.
My C++ professor isn't the greatest in the whole world and I'm having trouble getting my code to work using the cryptic examples he gave us. Right now, my code just outputs a binary value of 11111111 no matter what I set it too (unless its NULL then I get 00000000).
Here is my code:
#include <iostream>
#define useavalue 1
using namespace std;
void GiveMeTehBinary(char bin);
int main(){
#ifdef useavalue
char b = 'a';
#else
char b = '\0';
#endif
GiveMeTehBinary(b);
system("pause");
return 0;
}
void GiveMeTehBinary(char bin){
long s;
for (int i = 0; i < 8; i++){
s = bin >> i;
cout << s%2;
}
cout << endl << endl;
}
Thanks a ton in advance guys. You're always extremely helpful :)
Edit: Fixed now - thanks a bunch :D The problem was that I was not storing the value from the bit shift. I've updated the code to its working state above.
The compiler should warn you about certain statements in your code that have no effect1. Consider
bin >> i;
This does nothing, since you don’t store the result of this operation anywhere.
Also, why did you declare tehbinary as an array? All you ever use is one element (the current one). It would be enough to store just the current bit.
Some other things:
NULL must only be used with pointer values. Your usage works but it’s not the intended usage. What you really want is a null character, i.e. '\0'.
Please use real, descriptive names. I vividly remember myself using variables called tehdataz etc. but this really makes the code hard to read and once the initial funny wears off it’s annoying both for you when you try to read your code, and for whoever is grading your code.
Formatting the code properly helps understanding a lot: make the indentation logical and consistent.
1 If you’re using g++, always pass the compiler flags -Wall -Wextra to get useful diagnostics about your code.
Try this:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<8> x('a');
std::cout << x << std::endl;
}
it's actually really simple. to convert from decimal to binary you will need to include #include <bitset> in your program. inside here, it gives you a function that allows you to convert from decimal to binary form. and the function looks like this:
std::cout << std::bitset<8>(0b01000101) << std::endl;
the number 8 in the first argument means the length of the output string. the second argument is the value you want to convert. by the way, you can input a variable in binary form by declaring a 0b in front of the number to write it in binary form. note that to write in binary form is a feature added in c++14 so using any version lower than that won't work. here is the full code if you want to test it out.
#include <iostream>
#include <bitset>
int main()
{
std::cout << std::bitset<8>(0b01000101) << std::endl;
}
note that you don't have to input a binary number to do this.
#include <iostream>
#include <bitset>
int main()
{
std::cout << std::bitset<8>(34) << std::endl;
}
output:
00100010
Why not just check each bit in the unsigned char variable?
unsigned char b=0x80|0x20|0x01; //some test data
int bitbreakout[8];
if(b&0x80) bitbreakout[7]=1;
//repeat above for 0x40, 0x20, etc.
cout << bitbreakout;
There are a TON of ways to optimize this, but this should give you an idea of what do to.
#include <iostream>
using namespace std;
int main(){
int x = 255;
for(int i = numeric_limits<int>::digits; i >=0; i--){
cout << ((x & (1 << i)) >> i);
}
}
it's actually really simple. if you know how to convert decimal to binary, then you can code it easily in c++. in fact I have gone ahead and created a header file that allows you not only to convert from decimal to binary, it can convert from decimal to any number system. here's the code.
#pragma once
#include <string>
char valToChar(const uint32_t val)
{
if (val <= 9)
return 48 + val;
if (val <= 35)
return 65 + val - 10;
return 63;
}
std::string baseConverter(uint32_t num, const uint32_t &base)
{
std::string result;
while (num != 0)
{
result = valToChar(num % base) + result;
num /= base;
}
return result;
}
now, here is how you can use it.
int main()
{
std::cout << baseConverter(2021, 2) << "\n";
}
output:
11111100101