IBM developerWorks
           C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
1200+ fellow developers rate and compare features of the top IDEs, like Visual Studio, Eclipse, RAD, Delphi and others, across 13 categories. Enjoy this FREE Download of the IDE User Satisfaction Study by Evans Data Corporation. Download Now!
  #1  
Old January 10th, 2003, 07:21 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
not breaking when EOF

i'm not doing very well with these k&r exercises

can anyone tell me what wrong here please? :

the exercise is to do this loop:
Code:
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; i++)
	s[i] = c;

without any && or || 's. so here's my effort that does not work but i can't see why it doesn't work:
Code:
	while(i<lim-1) {
		c=getchar();
		if (c != '\n') {
			if (c != EOF) {
				s[i]=c;
				i++;
			}
		} else
			break;
	}


the problem with it is when i press control d to get the EOF character/sign it does not break out of the loop. or at least it does appear to. are if's considered loops? is that what is happening - the break only gets it out of the if? no, that's a complete guess and i don't think that's right. anyone?

Reply With Quote
  #2  
Old January 10th, 2003, 08:02 PM
vpopper's Avatar
vpopper vpopper is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2000
Location: Southern California
Posts: 73 vpopper User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 m 24 sec
Reputation Power: 9
In your snippet, if the char is not a newline, but it is EOF, i never gets incremented.

You can modify it like this:

Code:
while (i<lim-1) {
    c=getchar();
    if (c != '\n') {
        if (c == EOF) {
            break;
        }
         else {
            s[i]=c;
             i++;
        }
    } else
        break;
    }
}


Better yet, do something like this:

Code:
for (register int i=0; i < (lim-1); i++) {
  c = getchar();

  if (c == '\n') break;
  if (c == EOF)  break;

  s[i] = c;
}

Reply With Quote
  #3  
Old January 11th, 2003, 11:45 AM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
the first version of those two still doesn't break out of the loop - same problem

you did accidentally use an extra } so this is how i used it:

Code:
while (i<lim-1) {
		c=getchar();
		if (c != '\n') {
			if (c == EOF) {
				break;
			}
			else {
				s[i]=c;
				i++;
			}
		} else
        		break;
}


(so i've deleted a } from the end)

so is an if {} considered a loop? is that why this structure isn't working? - it's only brekaing out of the if! but that would make your second version not work too.
i ask/say that, but it doesn't feel right at all. but i can't see why it doesn't break out of the while loop having encountered an EOF in the above code.

the second version you posted works fine, so thanks. but i would like to get to the bottom of why the first version isn't working. any ideas?

Reply With Quote
  #4  
Old January 13th, 2003, 12:08 AM
bsuribabu bsuribabu is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2002
Location: Hyderabad
Posts: 17 bsuribabu User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to bsuribabu
Hi ,

First getchar() function enables u to give to input to u r program from standard input stream . When getchar() encountered in for loop testing section , first it takes the whole input from u to standard input stream until u press Enter. Then for each iteration it reads the next character from STDIN ( standard input stream) , I n ur code u r cheking for '\n' to be encountered for loop break and u r input is also seeking for the same, that's why when u press enter , it satisfies the both conditions . U r code is also working with Ctrl D , if it's not working it will store that character in u r string s.
Just test this statement

printf("%s",s);
and also

for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; i++)
{
printf("%u", c);
s[i] = c;
}
After pressing Enter only it will display the Interger quivalents of u r typed characters.

Then u will come to know.

I hope this may help u.

Suri

Reply With Quote
  #5  
Old January 13th, 2003, 03:14 AM
bsuribabu bsuribabu is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2002
Location: Hyderabad
Posts: 17 bsuribabu User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to bsuribabu
Hi,

u can use getch() which function prototype is in conio.h instead of getchar()
because getchar() waits for ENTER to be pressed which is not a actual interactive way.


Suri

Reply With Quote
  #6  
Old January 15th, 2003, 05:39 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
i still don't understand why it doesn't break out of this loop when crdl d is pressed:
Code:
while (i<lim-1) {
		c=getchar();
		if (c != '\n') {
			if (c == EOF) {
				break;
			}
			else {
				s[i]=c;
				i++;
			}
		} else
        		break;
}


if you follow the control through that code imagining c to hold eof, it goes into the if c!='\n' part as eof doesn't equal \n, then it should take the affirmative route from the if c equals eof, as c does equal eof. and the body of that if, is break so at that point the whole while loops should be broken out of - but it isn't and i can not see why :/ anyone?

Last edited by balance : January 15th, 2003 at 05:41 PM.

Reply With Quote
  #7  
Old January 15th, 2003, 10:13 PM
bsuribabu bsuribabu is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2002
Location: Hyderabad
Posts: 17 bsuribabu User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to bsuribabu
Just try ctrl-Z

Reply With Quote
  #8  
Old January 16th, 2003, 11:39 AM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
how does control z help me understand if if blocks are to be broken out of like loop blocks?!


do if blocks get treated in the same way as while loops? so if you have an if in an if and you break out of the 2nd if block, you only break out as far as the 1st if. *but you're still in that 1st if?*. is that correct? cause that'll explain it. i guess it must be. that's the only explenation. i just didn't think if blocks were treated in quite the same way as a while or for block but i guess they are. thanks.

Reply With Quote
  #9  
Old January 16th, 2003, 01:35 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,432 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 22 h 29 m 51 sec
Reputation Power: 784
Firstly ^Z is the EOF character for DOS and ^D is for *nix. Secondly, ^D (or ^Z in DOS) is not considered as an EOF character by the terminal, unless it happens the first character of the new line (because terminals run in cooked mode by default -- google for "cooked mode" and "cooked mode ioctl" if you like). As a test, do the following:
Code:
cat > testfile
this is the first line ^D [press enter]
This is the second line [press enter]
^D


Note that when you hit ctrl-d for the first line, the terminal did not recognize it as an end of file because it was not the first character in the line. DOS/Windoze users can perform the same test, using copy con testfile instead of cat > testfile and using ^Z instead of ^D. The results will be identical.

Well, what does this cooked mode do? For one thing, it buffers the input and does not pass things on to your program immediately as you type them. The first time your program will get any of the input you typed in is when you press enter. Also, your code breaks out of the loop if the character is a newline or an EOF. Since the terminal does not consider it an EOF char, unless it is the first character on a new line, your program breaks after you hit enter. Let's alter your program to only break on EOF.
Code:
#include <stdio.h>
int main(void) {
  char c;
  char s[100];
  int lim = 100, i = 0;

  printf("Enter a line\n");

  while (i<lim-1) {
    c=getchar();
    if (c != '\n') {
      if (c == EOF) {
        break;
      }
      else {
        s[i]=c;
        i++;
      }
    } /* else
             break; */
  }
  s[i] = '\0';
  printf("%s\n", s);
  return 0;
}

Now compile and run this program. Now input something like this:
Code:
this is the first line ^D [press enter]
This is the second line [press enter]
^D

Note how your program works this time.

Now to prove that your code does not read the characters until you hit enter, add this one line just under the line that reads c = getchar(); :
printf("Bing!\n");

Now run the program again. Note that your program will not print anything out unless you hit enter. This is because, in cooked mode, the terminal will buffer your input and not give it to your program immediately. The moment you hit enter, you'll see a series of "Bing!" being printed out, one for each character in your input.

If you want to get your terminal to start passing your input to the program immediately after you press each key, you can set it to raw mode using ioctl commands. This holds true for DOS, Windoze and *nix. Hope this helps!

Last edited by Scorpions4ever : January 16th, 2003 at 01:42 PM.

Reply With Quote
  #10  
Old January 16th, 2003, 04:40 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
right. i *think* i'm just about understanding this now

i had already worked out that the programme only gets input a whole line at a time. but i had completely missed the fact that eof doesn't count if it's not the first character. that's the part that was missing for me.

eof doesn't count unless it's the first character - this is just a terminal/console issue right? if you're not planning on using the console, other than for learning, then it's not something to think about too much about? or does this effect taking input from a higher level language? i guess not. or maybe it is? i'm thinking of in particular objective-c. doesn't matter - i'll find out.

but yup, thanks very much for a good explenation

Reply With Quote
  #11  
Old January 16th, 2003, 07:39 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,432 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 22 h 29 m 51 sec
Reputation Power: 784
Quote:
Originally posted by balance
eof doesn't count unless it's the first character - this is just a terminal/console issue right? if you're not planning on using the console, other than for learning, then it's not something to think about too much about? or does this effect taking input from a higher level language? i guess not. or maybe it is? i'm thinking of in particular objective-c. doesn't matter - i'll find out.

Yep, that's how the terminal works in cooked mode. It doesn't matter what language you're using, because the terminal works the same (unless someone writes an oddball language that overrides the default terminal settings).

Quote:
but yup, thanks very much for a good explenation

You're welcome

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > not breaking when EOF


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |