Ctrl+Z behaviour in terminal - windows

string s;
while(getline(cin,s)){
cout << "---" << endl
for(auto c: s) cout << int(c) << endl;
}
cout << "Exiting";
If my input is Ctrl+Z, then I press enter once, and my program exits immediately.
^Z
Exiting
If I enter a character before pressing Ctrl+Z, then I have to press enter twice, and my program does not exit.
s^Z
---
115
26
I had always interpreted Ctrl+Z as the EOF character. getline would continue until it reaches this character, at which point getline tests false and my program would exit. I'm curious why my program interprets Ctrl+Z as the substitute character 26, depending on whether there is a preceding character or not, and why it was necessary for me to press Enter twice in the second example?

26 is code of ^Z on your platform , and ^Z is a EOF marker for terminal, that's true. Characters with codes less than 32 are control characters for ASCII -compatible platform, I hope you know that. 26 isn't a substitute character, it's actual control code, ^Z or some "bug" character are substitutes. getline reads input until EOL (end-of-line, designated as CR by ASCII) or EOF (end of file, end of stream, designated as SUB) is encountered in stream, so ^Z is read with the second call of getline. That behavior is absolutely correct.
It is defined by platform (or, more precisely, by terminal type) if characters are sent to input buffer immediately or after some flush command occurred. Usual cause of buffer flush is EOL character, that's your ENTER (CR - Carriage return). Tat's why program receives EOF after Enter in your case. Note that some platform use LF (line feed) as EOL, and some - a pair of LF+CR. C literal '\n' is to be correctly translated into particular EOL marker.
Note, that you can use different delimiter:
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline(
std::basic_istream<CharT,Traits>& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
ASCII table with substitute Control+ :

Related

cmd converts em-dash to hyphen on pasting. Any workaround?

I want to be able to paste file paths into cmd with em dashes (—, alt 0151) in them.
cmd converts them to ones where the em dashes have been replaced by a hyphen.
Manual input:
(Keyboard) D:\—\image.png
(cmd) D:\—\image.png
Entering this would open the file as expected.
Pasted input:
(Clipboard) D:\—\image.png
(cmd) D:\-\image.png
Entering this would give me an error because a directory named hyphen doesn't exist.
This is baffling because the file system supports paths to have such a character - I can access this file if I type the path manually, and programs can open it just fine.
Why convert a character that is supported? If it wasn't supported when the conversion was added, why not remove the conversion when the support was added?
More importantly, how can I work around this while keeping the em dashes? I have programs that depend on such paths and it'd be inconvenient to change them in all of them.
Similar to:
How to deal with an em dash in a filename
Using “En Dash” in an input file to a batch file
Rename Files having EmDash using a Batch File
Changing the code page made no difference.
My workaround was to create an AutoHotKey script to parse the path being pasted and to send alt 0151 whenever it encounters an em dash.
It could be faster, but it works - which is miles better than receiving an error.
#SingleInstance, force
numpad7::
tooltip, exited!
Clipboard := stored
sleep, 300
exitapp
#IfWinActive ahk_exe cmd.exe
$^v::
cliptext := clipboard
stored := ClipboardAll
StringGetPos, garbage, cliptext, —
garbage =
if !ErrorLevel {
Loop, Parse, cliptext
{
char = %A_LoopField%
If (char == "—") {
clipboard := sentence
sendinput, ^v
SendInput {alt down}{numpad0}{numpad1}{numpad5}{numpad1}{alt up}
sentence := ""
} else if (char == "") {
char := " "
gosub define_sentence
} else {
gosub define_sentence
}
}
; send sentence when EOL
gosub define_sentence
Clipboard := sentence := SubStr(sentence, 1, -1)
sendinput, ^v
sleep 200
Clipboard := stored
stored =
sentence =
return
} else {
sendinput, ^v
}
return
define_sentence:
sentence := sentence . char
tool := "s= " . sentence . "`n" . "c= " . char
tooltip, %tool%
return
On another note, the highlight.js for autohotkey doesn't seem to work which is great.

trying the check if cin.get() leaves the end of line character in stream

1.i am trying to check whether the cin.get() leaves the end line character in stream and considered it for next input.
i have tried this code in code blocks but unable to provide input for next string,i am attaching code i have tried and the output .could anyone please explain.
#include<iostream>
using namespace std;
int main()
{
char s1[10];
char s2[10];
cout << "enter the first string: ";
cin.get(s1, 10);
cout << "enter the second string: ";
cin.getline(s2, 10);
cout << s1 << " " << s2;
return 0;
}
enter the first string: hello
enter the second string: hello
please explain the output
This get function reference says that your overload is
Same as get(s, count, widen('\n'))
And that overload of the function reads until (among other things)
the next available input character c equals delim, as determined by Traits::eq(c, delim). This character is not extracted (unlike basic_istream::getline())
[Emphasis mine]
So the newline is left in the input buffer, for the getline call to read as an "empty" line.
If you want to read lines, I suggest you use std::string and std::getline (which does read, and throw away, the newline).
cin.get() grabs the newline character by default. It will not leave the newline in the stream.

printf not print string after \n (Compiler GCC)

See my code
char t[]= "{\n abcdeffgjejgjergnjkengkknkn \n";
printf("%s",t);
char t1[]= "{ abcdeffgjejgjergnjkengkknkn \n aaffdefa";
printf("%s",t1);
Actual Output:
{
{ abcdeffgjejgjergnjkengkknkn
Expected output:
{
abcdeffgjejgjergnjkengkknkn
{ abcdeffgjejgjergnjkengkknkn
aaffdefa
Can any one help me why string is not getting print after \n (LF)?
Compiler - arm-none-eabi
Library header - Newlib
IDE: MCUExpresso
By default stdout (where printf writes) is line buffered. That means the output buffer is flushed (actually written) either when it's full or when you print a newline.
That's why the second part of the output isn't printed, because it's not enough to fill the buffer and you have no newline to flush the buffer.
You can flush explicitly yourself by calling fflush:
printf(...);
fflush(stdout);

End of input in XTerm usnig keyboard

How can I signal XTerm terminal to end of input. In my case, I run a C++ program in XTerm console and I want to signal the program the end of input by pressing some combination of keyboard buttons.(I tried Ctrl+D Ctrl+Z ).My program goes like this :
map<int,string>info;
string name;
int age;
cin>>name;
while( **?????????** ){ //Input till EOF , missing logic
cin>>age;
info.insert( pair<int,string>(age,name) );
cin>>name;
}
The program proceeds upon receiving the end of input signal from terminal.
You always need to check the input after reading, i.e., your program should look something like this:
while (std::cin >> name >> age) {
// do something with name and age
}
This will read from std::cin until something fails. You can check if std::cin.eof() is set to determine if having reached the end of the of the input is the cause of the error or there was some other failure, e.g., an attempt to enter something which isn't a number for the age.

How can I generate an EOF (or an ASCII 0) in a visual studio debug console?

I have a console-mode program running on Windows. The program calls getchar() in a loop unitl either an EOF or a 0 is returned. I'd like to enter one of the following as a test vector while running the debugger:
"abc\0" or "abc\EOF
I can't seem to consistently generate either. I tried the suggestion in this question by typing a bcCTRL-ZENTER". That returns 97,98,99,26 to my program, and then hangs on the next getchar() call.
Entering CTRL-D doesn't hlep either, getchar returns a 4 for the control char, then a newline char, and then it duplicates the line I just entered on the console. It's like VS is using the control characters as editing characters.
EDIT:
Here is a stripped down version of the code I am using. I see identical behavior in the debug console and in a command window.
#define MAXSZ 4096
int main(int argc, char **argv)
{
short int data[MAXSZ]={0}, i=0;
char c;
do {
if (i==MAXSZ) break;
c = getchar();
if (c!=EOF) data[i]=c;
} while (data[i++]!=0);
for (i=0;data[i]&&i<MAXSZ;i++)
putchar(data[i]);
}
How do I enter an EOF or an ASCII 0 in the Visual Studio debug a Windows console?
Try this one:
<Enter><Ctrl-Z><Enter>.
#Hans Passant solution works for me - should also work for OP.
1 To generate an ASCII 0, type (Ctrl+# ) or (Ctrl+2 )
2 To generate an EOF, type (Ctrl+Z Enter), but the input buffer needs to be empty. So this is typically after an (Enter), thus (Enter Ctrl+Z Enter).
But OP code has problems.
char c; // should be int ch
do {
...
c = getchar();
if (c!=EOF) data[i]=c;
} while (...);
In OP code, if the character ASCII 255 occurs , it gets assigned to a char (-1) which compares to EOF. Instead use int ch.
if (c!=EOF) data[i]=c;
// should be
if (c==EOF) break;
data[i]=c;
This prevents the code from looping forever or erring once an EOF occurs.
To enter ASCII 255
(Alt key down, num pad 2, num pad 5, num pad 5, Alt key up)

Resources