(C/C++) EOF in windows7 - c++

#include <cstdio>
void fcopy(FILE* from, FILE* to);
int main()
{
fcopy(stdin, stdout);
return 0;
}
void fcopy(FILE* from, FILE* to)
{
int c;
while ((c = getc(from)) != EOF) {
putc(c, to);
}
}
When I run this program, some unexpected behaviour happens with ^Z (Ctrl+z), which I would use to indicate EOF.
My input of "hello\n" executes the while loop in 'fcopy' to print the same.
"^Z\n" ends the program.
But if I input "blahblah^Zasdfasdf\n", while I expected the program to print "blahblah" and terminate, it prints "blahblah→" with a little arrow and waits for my input. Whatever I write down here will be copied down exactly the same; it seems to re-execute the loop while cutting away anything written after '^Z'.
in: hello
out: hello
in: hello^Z
out/in: hello→?? // "??" is my input
out: ??
in: ^Z
termination
Could anyone please clarify why the program works that way?
Thanks for any help, in advance.

This is because the Windows terminal program, which is what is reading your keyboard input and passing it on to your program, is handling Ctrl+Z like that. It only means "signal end of input" when pressed at the start of a line.
Note that EOF in C does not represent an actual ("physical") character, it's out-of-band signalling to indicate that "there was no character to be read, since the file has ended".

In general I would expect you that you should wait for ^Z and not EOF. ^Z is 0x1A ASCII character (http://en.wikipedia.org/wiki/Substitute_character). Also, you should definitely also check for EOF since file can end without ^Z
It seems that for some reason, console applications interpret ^Z as EOF when line is empty (I'm not sure why though - This could be legitimate behavior or simply a bug as suggested in https://connect.microsoft.com/VisualStudio/feedback/details/798951/c-getc-breaks-when-encountering-character-26-or-1a-hex-ascii-sub)
But the following code fixes it:
#include <cstdio>
#define CTRL_Z_SUB 0x1A // CTRL_Z substitue ASCII key
void fcopy(FILE* from, FILE* to);
int main()
{
fcopy(stdin, stdout);
return 0;
}
void fcopy(FILE* from, FILE* to)
{
int c = getc(from);
while (c != EOF && c != CTRL_Z_SUB) {
putc(c, to);
c = getc(from);
}
}

Related

Should I handle multiple instances of cin / stdin?

Below is a little program in C++ which is supposed to act as the cat linux binutil: it gets one or several inputs as detailed in the command line arguments (possibly specifying stdin via '-') and copy them onto the standard output. Unfortunately, it shows an unintended behaviour that I cannot understand the root causes of...
Upon the following command
./ccat - test.text
I hit CTRL-D directly without passing any character. I would expect the program to display anyway the content of test.txt, but instead, the program exits without passing any more characters onto the standard output stream.
Any idea on how I should correct my code below to have the correct behaviour in this situation? Should I handle multiple instances of the standard streams (cin, cout...)? If so, do you know how this can be achieved in C++?
Thank you in advance.
/**** ccat.cpp ****/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char **argv) {
if (argc <= 1) {
cout << cin.rdbuf();
} else {
vector<string> inputs;
for (int i=1; i<argc; ++i) inputs.push_back(argv[i]);
for (auto &in: inputs) {
if (in == "-" || in == "--") {
cout << cin.rdbuf();
}
else {
ifstream *fd = new ifstream(in);
if (!fd->is_open()) cerr << "Cannot open file \'" << in << "\'\n";
else cout << fd->rdbuf();
delete fd;
}
}
}
return 0;
}
I tried the following commands in sequence:
$ ./ccat > test.txt
Let's try this text.
I would expect a correct behaviour.
$ ./ccat - test.txt # I hit CTRL-D directly without passing any character first
$ ./ccat - test.txt
But when I add some characters before hitting CTRL-D... This works fine.
But when I add some characters before hitting CTRL-D... This works fine.
Let's try this text.
I would expect a correct behaviour.
As the example shows, I would expect in any of the two cases (last two shell prompts) that test.txt gets displayed onto the standard output, but this occurs only if I inject characters through the standard input first. Hitting CTRL-D straight away makes the program exit prematurely.
That's overload 10 here;
basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb );
and it says
If no characters were inserted, executes setstate(failbit).
In other words, cout is now in an error state and will not output anything.
Doing
cout.clear();
first of all in the else branch, or last of all in the if branch, should do it.
Note that sending end-of-file to standard input is usually not something you can recover or "restart" from, so you might only be able to use one standard input "section".

How to read data from stdin without waiting for a newline character [duplicate]

Is there a way to process command line input before seeing the newline character? I'm thinking of making a program that supports autocomplete (like the ones found in search engines or iOS keyboard).
To be more specific, my program will prompt for user input when started, and for each character input, I would like to output something BEFORE the newline character(or EOF) is input.
The following code snippet is what I have tried:
int main(){
char ch;
while ( (ch = cin.get()) != cin.eof() )
{
cout << ch << flush;
}
}
expected: for each character input, output that character.
actual: does not output anything UNTIL the program sees an eof.
In a Unix-like system, you can achieve this by changing the terminal to non-canonical input mode. Terminal supports canonical input which gathers the entire line for editing until the end of line character or Ctrl-D is pressed. As a result, the application often sees whole line on the read() system calls. On the other hand, non-canonical input does no line buffering; the input characters are made available to the program as soon as they are typed.
Here is a Linux C/C++ example of how to set -icanon flag (non-canonical) programmatically.
#include <iostream>
#include <termios.h>
#include <unistd.h>
int main() {
struct termios old_tio, new_tio;
tcgetattr(STDIN_FILENO, &old_tio);
new_tio = old_tio;
new_tio.c_lflag &= (~ICANON);
tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
char c;
while (fread(&c, 1, 1, stdin))
std::cout << c << std::endl;
return 0;
}

using getchar() and getting stuck in loop [duplicate]

For my homework assignment, I need to implement Horners Algorithm for converting between bases.
I have been told to use getchar() for this assignment. But I am having a problem where when I hit enter, the program doesn't terminate and just takes in more chars.
Example:
bryce> ./pa1
Enter the fromRadix:16
Enter the toRadix:2
abc
abc
^C
bryce>
Code:
int readRadixA(int radixA)
{
char myChar = getchar();
int result = 0;
int run = 0;
while(myChar != EOF)
{
if(myChar == "\n")
break;
Horners();
myChar = getchar();
}
return result;
}
I am not asking for help implementing Horners; I am asking for help to terminate the getchar() correctly.
if(myChar=="\n")
^ ^
You're comparing myChar wrong. Try this instead:
if(myChar == '\n')
^ ^
A second problem is that getchar returns int, not char. Maybe you can rewrite it like this:
int myChar;
while((myChar = getchar()) != EOF && myChar != '\n')
{
/* Your stuff. */
}
EDIT
In light of comments, I think some stdio operation before that while is leaving a \n in the buffer.
Instead of scanf("%d", &radix) try:
scanf("%d ", &radix);
^
That space will make scanf eat the remaining blanks (including the newline).
Check the return type of getchar(). Yes, it's an int. That's because EOF must have a value that can be distinguished from a valid character. myChar must actually be made to be int.
Try this code
int readRadixA(int radixA)
{
char myChar;
int result = 0;
int run = 0;
do
{
myChar = getchar();
// implement horners here
}while(myChar != 13);
return result;
}
I checked your code I think you are leaving a '\n' in the input keyboard buffer after the toRadix.
And their is one more thing that
getchar()
reads all the characters in one go till a '\n' is received.
And there is one more mistake you have committed by comparing a
char to a pointer e.g mychar=="\n"
further information about your implementation of toRadix can be really helpful to answer your question
On linux, to end the standard input, you have to type  Ctrl-D. The kernel and tty layers makes that an end-of-file mark or condition. Then getchar gives EOF (which is not a valid char, for example on systems where char are unsigned bytes between 0 and 255, EOF could be -1).
Notice that feof(3) is valid only after a read operation (e.g. getchar, fgets, etc...) so coding while(feof(stdin)) is generally wrong (contrarily to what I wrote in the previous version of this answer). You'll better test that getchar is returning EOF so your myChar should be an int (not a char).

fgets() does not return NULL on empty string

I recently tried to use fgets() instead of scanf() to read a string for code security reasons. I used a simple function that I found here to check for errors (no input and too long input). The problem is that whenever i press "ENTER" without actually writing anything, fgets() doesn't return NULL and my program is not able to show the NO_INPUT error.
Here's main.cpp:
#include <stdlib.h>
#include <stdio.h>
#include "utilities.h"
int main() {
int rc;
char str[20];
rc = getLine("Enter string: ", str, sizeof(str));
if(rc == NO_INPUT) {
printf("[ERROR] No input\n\n");
} else if(rc == TOO_LONG) {
printf("[ERROR] Input is too long\n\n");
} else {
printf("This is your input: \"%s\"\n\n", str);
}
system("pause");
}
Here's utilities.h:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
int getLine(const char *msg, char *buff, size_t len) {
if(msg != NULL) {
printf("%s", msg);
fflush(stdout);
}
if(fgets(buff, len, stdin) == NULL /*[+]*/ || strcmp(buff, "\n") == 0) {
//[-] fflush(stdin);
return NO_INPUT;
} else if(buff[strlen(buff)-1] != '\n') {
//[-] fflush(stdin);
return TOO_LONG;
} else {
buff[strlen(buff)-1] = '\0';
//[-] fflush(stdin);
return OK;
}
}
And here's the output:
Enter string:
This is your input: ""
Press any key to continue . . .
I solved my problem by replacing the first if statement in utilities.h with if(fgets(buff, len, stdin) == NULL || strcmp(buff, "\n") == 0). Doing this, my program will check for input errors OR for empty strings and return the NO_INPUT flag.
Thanks to everybody who commented and #Peter for answering. I added the aforementioned if statement in utilities.h and removed every fflush(stdin) occurrence. The code now looks as above.
Your problem that you "fixed" is believing that a end of line should be treated as end of input.
NULL is an indication from fgets() that it encountered an error or the end of input when reading from the file (or stream). A blank line is neither an error nor a marker of end of input. A human (typing on a keyboard) might choose to interpret a newline as end of input, but a computer program does not - after all, there is nothing stopping a user entering more than one line of input.
Practically, fgets() reads a line and indicates the end of that line with a '\n' character. Let's say, we have a file containing
ABC
DE
FGHIJ
(blank lines interspersed in three lines of text, followed by end of the file).
Let's also that buffer is an array of five char, and that we read that file using consecutive statements of the form fgets(buffer, 5, file).
So what will fgets(buffer, 5, file) do on each call. Well, with 1 representing the first call, 2 representing the second call, etc we will see results of
"ABC\n" stored into buffer;
"\n" stored into buffer; (first blank line)
"DE\n" stored into buffer;
"\n" stored into buffer; (second blank line)
"FGHI" stored into buffer;
"J\n" stored into buffer; and
fgets() returns NULL, and nothing is stored into buffer.
The first six calls will all return &buffer[0] - not NULL - since no error is encountered reading from the file. Even though there are two blank lines in the input. The last line, which is longer than the buffer (with the '\n' counted) is read in two parts.
Incidentally, your code is using fflush(stdin). Unfortunately, fflush() only has defined behaviour on OUTPUT streams or files. Using it on stdin (or any input stream) gives undefined behaviour. If it is actually discarding input (which it does with some implementations of the C standard library), you are getting lucky - there are real-world compilers where the resultant behaviour does not discard input.

End of File(EOF) of Standard input stream (stdin)

Does stdin have any EOF? For example, if I start reading from stdin using fread or read, then will the following loop end?
while ((c = read(0, buffer, BUFSIZ)) > 0) {
.
.
.
}
If the answer to this question is no, then is there any way to add EOF to stdin?
Speaking about EOF in stdin: when you redirect input from file, e.g.:
program <input.txt
the file already has an EOF, so this is not a problem. In console you can simulate EOF flag. In UNIX systems it is Ctrl+D, in Windows Ctrl+Z. When you type this in the console, program will behave like it has just reached end of input file.
Edit
According to a question asked by OP:
So does it means that stdin don't have EOF and we have to insert them manually using Ctrl+Z or Ctrl+D?
Actually -- yes. One may consider stdin (not redirected, but taken from the console) as infinite file -- no one can tell where does it end. The end of input file, where input ist stdin, must be told literally by Ctrl+D or Ctrl+Z.
I have never programmed C in windows so I can't tell you but in bash, the program will get an EOF when you type end of data (Ctrl+D)
while ((c = read(0, buffer, BUFSIZ)) > 0) {
You don't say the type of c but using that name implies that it's a char. Note that the EOF value for iosteams is an (int) -1. Storing that into an unsigned char will get you a value of 255 which will not match EOF.
The way to test for EOF is to check the return value of fread, and then use feof:
while( fread( ... ) ) { // loop so long as fread does not return zero
// do something
}
if ( feof( stdin ) ) {
// read failed because of EOF
}
else {
// some other error
}
Your solution is tagged C++, so here's some C++.
std::string lols;
while(!(std::cin >> lols).eof()) { // This loop will end when EOF is reached
// Process string
}
First getchar() is really getc(stdin) so getc(FILE) you can read more from that. getchar() gets you last unprocessed character from input stream or stdin pressing enter is '\n'. if the stdin is empty getchar forces a pause to get input.
Say in a program I call getchar() at first the stdin is empty so it pauses for input. If I enter ab'\n' the first getchar() will get 97 the ascii of 'a'. the next time i call getchar() i will get b , then again getchar() will have '\n'.
To prove this write this code.
int choice;
do
{
cout << "Enter input:" ;
choice = getchar();
cout << "Last getchar(): " << choice << ":" << (char) choice ;
if( choice == '0' || choice == EOF)
{
cout << "Exited loop" << endl; // EOF is ctrl+z in windows
break;
}
}while(true);
I do believe stdin is a global so until getchar() or similar function gets called it to clear the stream the characters remain there which can cause bugs later if you use getchar() elsewhere. As people have mentioned you can use gets(char[]) which puts all characters until newline into the character array. The problem with this is you need a char[] larger than input or you will get errors. The nice thing is gets(char[]) does clear stdin so you can make a dumby buffer to clear stdin or process it.
I hope this is informative.