Why is the letter 'D' missing in the output? - c++

#include <iostream>
using namespace std;
int main() {
char ch1 = 'A';
char ch2 = 'B';
char ch3 = '\n';
cout << ch1 << '\t' << ch2 << ch3;
cout << 'C' << '\t' << 'D' << '\b' << ch1 << ch3;
//return 0;
system("pause");
}
Output is:
A B
C A
Why is the last letter A and not D?

Everything you cout gets outputted. It's just that a terminal will interpret '\b' as "go back one character". Try redirecting the output to a file and examine it with a (hex)editor to see that all the characters (including '\b') are there.
At a first glance, one might think that terminals print output as-is. That's incorrect, though. Terminals change the way they behave whenever they encounter one of special terminal control sequences or characters. The '\b' (=0x08=backspace) character is one of those. More can be found at http://ascii-table.com/ansi-escape-sequences.php . You can try printing some of those to a terminal and see it change colors, rewrite current lines and so on and so forth. In fact, you can use these special sequences and characters to make complete GUI-like apps in the command-line.
Note however, that not with all programs you can rely on the "redirect to a file" trick to see what terminal control sequences they write to stdout. Many programs detect whether they're writing to a terminal or not and adjust their usage (or lack thereof) of terminal control sequences accordingly.

\b is a backspace, so you move the cursor one position to the left and then you overwrite the D with ch1 which holds an A.

cout << ch1 << '\t' << ch2 << ch3;
prints A, a tab, B and then a newline character.
cout << 'C' << '\t' << 'D' << '\b' << ch1 << ch3;
prints C, a tab, D, then moves the cursor behind D, prints A(This overwrites the character D) and then, prints a newline character.
\b is an escape sequence which represents a backspace. It moves the cursor one step behind.

Others have explained why D is overwritten by A, because \b is the escape sequence for backspace.
I'd like to add that the output might be different on different machines. How \b is actually displayed is up to the implementation of the terminal.

Why is the last letter A and not D?
Because the last visible character you output is A:
cout << 'C' << '\t' << 'D' << '\b' << ch1 << ch3;
ch1 is A, ch3 is a new line. And D is not shown because you erased it with '\b'

What this line cout << 'C' << '\t' << 'D' << '\b' << ch1 << ch3; does is:
Print C,
Make space (tab \t)
Print D
Go back (backspace \b)
Print A where D was (D is now erased)
New line (\n)

Because of \b jumping back and overwriting D

Due to this line in code //'D' << '\b' << ch1 << ,
'D' will print D
'\b' is backspace, so D gets erased
ch1 prints value that is A

Related

My program that converted 26 letters into ascII did not show me right answer

Here is my part code:
I guess there is something wrong with my 3rd line code. But I can not figure it out.
char letter1{'a'};
while(letter1 <= 'z') {
std::cout << letter1<<' '<< static_cast<int>(letter1)<<'\n';
++letter1;
}
Here is my screenshot for program result:
You have a double space here <<' '<<. You cannot have two characters in a character literal. Change the code to use double quotes like this
std::cout << letter1<<" "<< static_cast<int>(letter1)<<'\n';
Or just output a single space, like this
std::cout << letter1<<' '<< static_cast<int>(letter1)<<'\n';

Writing a backspace in a file

int main(){
std::cout << "Insert file name / or path. \n NOTE: ONLY INPUTS. DELETES PREVIOUS DATA.\nV.6" << std::endl;
std::string filen;
std::cin >> filen;
std::ofstream myFile;
try{
myFile.open(filen, std::ios::out);
}
catch(std::fstream::failure){
std::cout << "Could not open file!\n Make sure the name and data type are valid.";
system("pause");
}
while(true){
int press = getch();
if(press == 43) myFile.close();
if(press == 8){myFile << "\b" << " " << "\b";std::cout << "\b" << " " << "\b" << std::flush;}
if(press == 13){ myFile << "\n"; std::cout << "\n" << std::flush;}
if(press != 43 && press != 127 && press != 13 && press != 8){myFile << (char)press;std::cout << (char)press;}
}
return 0;
}
Whenever I choose a text file and I press backspace, and I check the document and when I check the text document, I get random characters like so:
Those are not "random characters"; those are backspace characters! i.e. exactly the input you gave.
This can be verified with a hex editor (or piping the output of your program through hexdump et al).
If you wish to replicate the behaviour of common shells, you'll have to write your own code to identify the backspace character and, instead of appending it to myFile, instead eliminate the previously-entered character.
As #BoundaryImposition pointed out already, writing "\b" to your file, will actually write a binary backspace character to your file. What you probably want instead is myFile.seekp(-1, std::ios_base::cur);. If you are on win/dos machine you likely need extra care with '\n' characters because they are translated into 0x0d 0x0a when written to a text stream (thus they require to seek back 2 positions instead of 1).
But generally, if you are not dealing with very huge files, it will be way easier to just store the content in a std::string (using pop_back or erase, to remove characters if needed) and write it to the file when you are finished.

Why do I obtain this strange character?

Why does my C++ program create the strange character shown below in the pictures? The picture on the left with the black background is from the terminal. The picture on the right with the white background is from the output file. Before, it was a "\v" now it changes to some sort of astrological symbol or symbol to denote males. 0_o This makes no sense to me. What am I missing? How can I have my program output just a backslash v?
Please see my code below:
// SplitActivitiesFoo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
string s = "foo:bar-this-is-more_text#\venus \"some more text here to read.\"";
vector<string> first_part;
fstream outfile;
outfile.open("out.foobar");
for (int i = 0; i < s.size(); ++i){
cout << "s[" << i << "]: " << s[i] << endl;
outfile << s[i] << endl;
}
return 0;
}
Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.This is because in the actual program the string will be read in from a file and parsed then sent to another function. I guess I could figure out a way to programmatically add backslashes...
How can I have my program output just a backslash v?
If you want a backslash, then you need to escape it: "#\\venus".
This is required because a backslash denotes that the next character should be interpreted as something special (note that you were already using this when you wanted double-quotes). So the compiler has no way of knowing you actually wanted a backslash unless you tell it.
A literal backslash character therefore has the syntax \\. This is the case in both string literals ("\\") and character literals ('\\').
Why does my C++ program create the strange character shown below in the picture?
Your string contains the \v control character (vertical tab), and the way it's displayed is dependent on your terminal and font. It looks like your terminal is using symbols from the traditional MSDOS code page.
I found an image for you here, which shows exactly that symbol for the vertical tab (vt) entry at value 11 (0x0b):
Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.
Well, I just saw you add the above part to your question. Now you're in difficult territory. Because your string literal does not actually contain the character v or any backslashes. It only appears that way in code. As already said, the compiler has interpreted those characters and substituted them for you.
If you insist on printing v instead of a vertical tab for some crazy reason that is hopefully not related to an XY Problem, then you can construct a lookup-table for every character and then replace undesirables with something else:
char lookup[256];
std::iota( lookup, lookup + 256, 0 ); // Using iota from <numeric>
lookup['\v'] = 'v';
for (int i = 0; i < s.size(); ++i)
{
cout << "s[" << i << "]: " << lookup[s[i]] << endl;
outfile << lookup[s[i]] << endl;
}
Now, this won't print the backslashes. To undo the string further check out std::iscntrl. It's locale-dependent, but you could utilise it. Or just something naive like:
const char *lookup[256] = { 0 };
s['\f'] = "\\f";
s['\n'] = "\\n";
s['\r'] = "\\r";
s['\t'] = "\\t";
s['\v'] = "\\v";
s['\"'] = "\\\"";
// Maybe add other controls such as 0x0E => "\\x0e" ...
for (int i = 0; i < s.size(); ++i)
{
const char * x = lookup[s[i]];
if( x ) {
cout << "s[" << i << "]: " << x << endl;
outfile << x << endl;
} else {
cout << "s[" << i << "]: " << s[i] << endl;
outfile << s[i] << endl;
}
}
Be aware there is no way to correctly reconstruct the escaped string as it originally appeared in code, because there are multiple ways to escape characters. Including ordinary characters.
Most likely the terminal that you are using cannot decipher the vertical space code "\v", thus printing something else. On my terminal it prints:
foo:bar-this-is-more_text#
enus "some more text here to read."
To print the "\v" change or code to:
String s = "foo:bar-this-is-more_text#\\venus \"some more text here to read.\"";
What am I missing? How can I have my program output just a backslash v?
You are escaping the letter v. To print backslash and v, escape the backslash.
That is, print double backslash and a v.
\\v

ifstream to get then next character

So I have a while look that checks every character in a file.
while (infile.get(ch))
The problem is that in the same loop I have to check the next character to check for some validation.
Is there anyway I could move the next character while keeping track of the current one?
Thanks
Use the peek() method so you will be able to look at the next character before extracting it. Here's an example:
std::istringstream iss("ABC");
for (char c; iss.get(c); )
{
std::cout << "Current character is: " << c << std::endl;
if (iss.peek() != EOF)
std::cout << "Next character is: " << (char)iss.peek();
}
This should output:
Current character is: A
Next character is: B
Current character is: B
Next character is: C
Current character is: C

Spaces instead ascii character

#include <iostream>
int main() {
for(int i=0;i<18;i++)
std::cout << (char)i << '\n';
}
OUTPUT is:
But where are other characters?
The characters you are expecting to see are not ASCII. In ASCII, the codes below 32 signify what is called control characters, which were originally intended to control functions on teletype printers. Many of them don't apply to modern terminals, so your terminal just picked some characters (or got them from some other encoding), such as the faces and the card suits, to use for those codes. Some of the ASCII control characters are still applicable though.
7 is a called the bell character ('\a'), you may have heard a beep.
8 is a backspace ('\b').
std::cout << "abc" << (char)8 "def"; // where's the c?
9 is a horizontal tab ('\t'), so that's invisible, but you'll probably notice it if you print visible characters before and after it.
std::cout << "before" << (char)9 << "after";
10 is a line feed, a.k.a. newline ('\n')
13 is a carriage return ('\r').
std::cout << "hello" << (char)13 << "world"; // where's the hello?
Your results may vary depending upon which terminal you use.