# 1.4Ctrl+D and Ctrl+Z issues (1.4)

#### maneet

##### Member
C++ Student
I am stuck at one point in HW 1.4 ex 1. What does the 'characters from the keyboard can be stopped when the shutdown-code ^D (CTRL + D) is entered. ^D has the ASCII-value 4' mean? I mean how can I use it in my code? So far, I have worked on the code in a way that when the user hits enter, the program counts the no. of characters and words, but I am assuming since the program is also supposed to count number of new lines, then enter shouldn't be the end of user input right? Which gets me back to the ^D shutdown code, which I am not sure how to use. Can anyone guide me here? Thanks!!

#### AlanComan

##### Member
Hi Maneet,

I checked that indeed Ctrl+D gives an ASCII character of 4, this is what you check for in your while loop.

http://www.cs.tut.fi/~jkorpela/chars/c0.html

Try with Ctrl+4 (not with enter) and let us know if it works (it should).

#### maneet

##### Member
C++ Student
oh ok. So if I am working on mac, it should be command+4 right? Because I am having difficulty making that work...

#### maneet

##### Member
C++ Student
So I noticed something interesting while working on mac (I am using xcode), so thought I should share it here for other mac users. The ctrl+D worked, however, only worked the first time I ran the code. I had real difficulty making it work after that..

#### RogerLiao

##### Member
C++ Student
I have a question on 1.4.6. I made the loop (Frame)like:
do{
c=getchar();
//switch .....
}while(c!=EOF);

But this code will lead to a problem. If my input is: Hello World^z. The loop will not exist. It only exists when my input ^z is the first character of a newline.

I modified my code to:
do{
c=getchar();
//switch .....
}while(c!=EOF&&c!=26);

It solved the problem but is there a better way to do this since the HW requires us to use EOF only?

#### RedPanda

##### Member
C++ Student
I have a question on 1.4.6. I made the loop (Frame)like:
do{
c=getchar();
//switch .....
}while(c!=EOF);

But this code will lead to a problem. If my input is: Hello World^z. The loop will not exist. It only exists when my input ^z is the first character of a newline.

I modified my code to:
do{
c=getchar();
//switch .....
}while(c!=EOF&&c!=26);

It solved the problem but is there a better way to do this since the HW requires us to use EOF only?
I think all that ctrl-z thing is OS dependant. Sometimes typing crtl-z twice at any point of the line helps. Also I believe it is ctrl-d not ctrl-z if you're running Unix.
I have the same problem. I can only force EOF by pressing ctrl-z in the beginning of the line following by enter.
I'm waiting for TA's or Dr. Duffy's response with you .

#### RogerLiao

##### Member
C++ Student
I think all that ctrl-z thing is OS dependant. Sometimes typing crtl-z twice at any point of the line helps. Also I believe it is ctrl-d not ctrl-z if you're running Unix.
I have the same problem. I can only force EOF by pressing ctrl-z in the beginning of the line following by enter.
I'm waiting for TA's or Dr. Duffy's response with you .
Yeah, I tried ctrl-d, it works perfectly. I am waiting too.

#### RedPanda

##### Member
C++ Student
Yeah, I tried ctrl-d, it works perfectly. I am waiting too.
Do you run Unix?

#### RogerLiao

##### Member
C++ Student
Do you run Unix?
Actually not, I am using Windows and that's the reason I feel confused.

#### AlanComan

##### Member
Can anybody on Windows look into Roger's issue with Ctrl-Z? I am on ubuntu and can't help him with his OS specific question.

#### Manos Makrakis

##### Active Member
C++ Student
This is
I have a question on 1.4.6. I made the loop (Frame)like:
do{
c=getchar();
//switch .....
}while(c!=EOF);

But this code will lead to a problem. If my input is: Hello World^z. The loop will not exist. It only exists when my input ^z is the first character of a newline.

I modified my code to:
do{
c=getchar();
//switch .....
}while(c!=EOF&&c!=26);

It solved the problem but is there a better way to do this since the HW requires us to use EOF only?
-----

This is interesting. I am on Windows 7 and I implemented originally this exercise without bothering that much about the specifics of how ^Z works, as I thought it was out of scope for the purposes of this exercise. So I assumed entering ^Z as the first character of a newline to terminate this loop would satisfy the requirement. However I looked up the behavior of EOF under different OSs and according to at least this article in Wikipedia it looks like that for DOS the EOF or Ctrl + Z maps to ascii 26 . So I would assume that if the test condition tested for 26 alone it would be enough to satisfy the requirements of the exercise. Not sure if Daniel Duffy agrees with this approach.

#### RogerLiao

##### Member
C++ Student
This is
-----

This is interesting. I am on Windows 7 and I implemented originally this exercise without bothering that much about the specifics of how ^Z works, as I thought it was out of scope for the purposes of this exercise. So I assumed entering ^Z as the first character of a newline to terminate this loop would satisfy the requirement. However I looked up the behavior of EOF under different OSs and according to at least this article in Wikipedia it looks like that for DOS the EOF or Ctrl + Z maps to ascii 26 . So I would assume that if the test condition tested for 26 alone it would be enough to satisfy the requirements of the exercise. Not sure if Daniel Duffy agrees with this approach.
Actually I tried use Ctrl + Z alone, which lead to the problem that the loop will exit when Ctrl + Z is the start of a new line. And that's the reason I used both of them. I am not quite sure the inside detail about this issue, but I agree with you that it should not be a major issue.

#### Andrew M

##### Member
C++ Student
SimonZheng and others

Right its the weekend so its time to finish this level off...

Because I wasn't able to get the required Ctrl-D/Z behaviour on my unix machines (mac/linux) I found an old windows pc to test things on. However testing my code on this machine I've found that behaviour is different than I expected for 1.4.1,2,&3...

On the unix machines I was finding that for Ctrl-D I was having to test for EOF and not ASCII 4 (which meant that 1.4.6 was similar), additionally this would only work if Ctrl-D was after a newline.

With the windows PC I find that Ctrl-D seems to register when I follow with a newline. Am I missing something here? I interpreted the exercise as simply typing characters and exiting once Ctrl-D is pressed and I simply can't get this behaviour.

I guess I am worrying about nothing however I wanted to get 100% in the first levels.

#### SimonZheng

##### New Member
andrew, please use EOF. Usually macro makes your program more portable on different platform.

Just checked my Mac, \usr\include\stdio.h

#define EOF(-1)

According to man page of getchar(), it return EOF if any error. Following ANSI standard is a good practice.

#### Marcelo

##### Member
C++ Student
Hi Folks,
I am working on my version of freq.ccp, exercise 6 section 1.4. I can't get my Cntrl-Z (EOF) to work properly.
It seems that it works only when cntl-Z is the first char in the line. If I cntl-Z in the middle of the line it does not work.

#### APalley

##### Well-Known Member
In resolution to the ongoing issue about cntrl-Z and cntrl-D:

getchar() will return EOF depending on the OS if it's on a new line -- UNIX based OS EOF is defined as ^D. Dos based, ^Z. Otherwise, it will return the ASCII code for that combo. So 4 for ^D, and 26 for ^Z. In short, it really all depends on the driver/OS, and how/when it interprets a control as an EOF or ASCII value (which have some legacy use)...

So a useful thing to do would be to check for EOF in combination (OR) with the respective ASCII code.

#### Ridwan

##### Member
C++ Student
Hi Palley,

I'm your new tutee. It's a bit out of topic but just to fulfill my curiosity.

Coz when i'm doing the same loop condition for both ^D and ^Z it will give me different response

My general loop will be as below s for ^D and ^Z
Code:
char a =0;

while (int (a) != 4)
{
char c;
c = getchar();

......

a = int (c);
}

char a =0;

while (int (a) != 26)
{
char c;
c = getchar();

......

a = int (c);
}
For ^D (ASCII no 4) it will end the loops regardless where I typed it (i.e. new line or end of line)
However for ^Z (ASCII no 26) it won't end the loop if I typed it in new line. So to remedy it I'm using below expression

while (int (a) != 26 && a != EOF).

I'm running on Windows Vista Home Premium 32 bit.
So should I change the expression of my ^D as well??

#### APalley

##### Well-Known Member
Hi Palley,

I'm your new tutee. It's a bit out of topic but just to fulfill my curiosity.

Coz when i'm doing the same loop condition for both ^D and ^Z it will give me different response

My general loop will be as below s for ^D and ^Z

char a =0;

while (int (a) != 4)
{
char c;
c = getchar();

......

a = int (c);
}

char a =0;

while (int (a) != 26)
{
char c;
c = getchar();

......

a = int (c);
}

For ^D (ASCII no 4) it will end the loops regardless where I typed it (i.e. new line or end of line)
However for ^Z (ASCII no 26) it won't end the loop if I typed it in new line. So to remedy it I'm using below expression

while (int (a) != 26 && a != EOF).

I'm running on Windows Vista Home Premium 32 bit.
So should I change the expression of my ^D as well??
The way you did is fine. See the previous posts, above, as to why this is the case !

#### Lucas Ter

##### Member
C++ Student
Hi APalley,

Is there any reason why my computer is reading EOF as -1?

I used printf to confirm it and instead of 26, it is treating EOF as -1.

Just curious