![]() |
|
#1
|
|||
|
|||
breaking an infinite loop through stdinHi there,
Some of the thinks I've thought many times is how to break an infinite loop by an instruction coming from stdin. Let's suppose the following code: CPP / C++ / C Code:
As all of you may know the loop gets stop at scanf. It would be nice if the loop could keep on iterating and at the same time listening for "1", if it arrives the loop is broken. A couple of days ago (better late than never ;-) ) I got to know about fork(), and I started to think about forking to solve the previous problem. I wanted to ask the experienced people which use to post here, if I should use fork or there's an easier, better approach. In case of forking, which one should be the parent process and which one the child. Without previous experience I would say that the parent process should listen for a signal and the child one execute the loop. There's somewhere a good tutorial about that stuff, something as good as what Howard has posted about pointers... Thanks! |
|||
|
#2
|
|||
|
|||
Re: breaking an infinite loop through stdinQuote:
The fact is that there are no standard C library functions (C++ either) that do what you would like. Input from stdin on all implementations with I am familiar is buffered. That is, when the user types something on the keyboard, characters are put into a buffer (hidden from the program) nothing is offered to the program's scanf or getchar or any other standard library function until the user presses the 'Enter' key. Sorry. Some compilers supply a function called kbhit() that is used for exactly what you have in mind. I believe taht Windows API functions to get chars one at a time also exist. Some compilers and operating systems allow low level manipulation of input device functions to set the keyboard into a mode that supplies characters one at a time as they are entered. I know that it is sometimes very desirable to have the behavior that you desire, and, in fact, some applications might require it. However, there are no standard (portable) solutions. Getting to know about fork() and understanding its uses may be a Good Thing, but won't help in your particular problem. Regards, Dave Footnote: The fork() function is also not a standard C library function, and not all operating systems/compilers will support it. |
|
#3
|
|||
|
|||
Re: breaking an infinite loop through stdinI see...
And it is possible to catch a signal, like Ctrl+C and finish the program gracily? |
|
#4
|
|||
|
|||
Re: breaking an infinite loop through stdinIf you are in Linux/UNIX (assumed because of fork() ) -
Look into termios, which allows you to set the tty driver to canonical/non-canonical mode. canonical = read line after return key pressed, non-canonical = read each keystroke You can google for example code. Also in UNIX, there usually is a character that is defined as EOF for stdin. The defacto standard is ctrl-D for eof. In your .profile (or .bashrc) or in /etc/profile there will be an entry like CPP / C++ / C Code:
Regardless of which terminal mode you are in, calls to read stdin after a ctrl-D will return no characters ( ie, getchar returns EOF fgets returns NULL) and feof(stdin) returns non-zero once you have cleaned out the input buffer. This is preferable to ctl-c (SIGINT) because you would have to establish a signal handler to exit gracefully and not lose data. |
|
#5
|
|||
|
|||
Re: breaking an infinite loop through stdinQuote:
You haven't told us what compiler and operating system you are using. The point of my post is that various methods are available depending on what you have. If you are using Microsoft or Borland compilers on Windows XP, then kbhit() and getch() functions usually found in <conio.h> may be the ticket. If you have the equivalent of kbhit() and getch(), then all keystrokes can be intercepted so that Ctrl-c has no special effect---in other words your program handles it. Of course other desirable features such as command-line editing (backspace to delete previous character, handling of esc or tab or other control keys, for example) are also eliminated, so that your usual programmed input methods must necessarily be more complicated. Also, mixing "normal" getchar or scanf or fgets with the special functions may require some experimenting to get the desired effects. But that's always the case when you introduce non-standard I/O functions. If you would tell us exactly what you are working with, perhaps someone can give specific help. For example GNU/gcc on Linux? GNU/gcc/cygwin on Windows XP? I have examples of functions that are more-or-less equivalent to kbhit() and getch(). They require a little setup, but other than that, they fit into Borland or Microsoft compatible source code, and can give equivalent results. (At least I have some stuff that works for me.) Regards, Dave Footnote: Since the vast majority of questions that I see here are from less-experienced programmers, I usually recommend that people get a thorough grounding in use of standard C library functions and a somewhat higher level of competence in using C programs in problem-solving before going off onto tangents regarding more exotic input/output functions. The point being: get very familiar with things that are universal (or at least things that have greatest chance of portability) first. When fancy I/O becomes a requirement, you will probably abandon the command-line programs for some graphics interface that can actually be made attractive and can be a showcase for your artistic creativity. After all, no matter how you "dress up" your command-line program, it's still far below the standards that users have rightfully come to expect. However, I do understand that there are places in command-line programs where functions like kbhit() and getch() are desirable. |
|
#6
|
|||
|
|||
Re: breaking an infinite loop through stdinHi guys,
Yes, you are right... sorry. I'm using linux (FC or SUSE). Dave: could you post for us some of the examples you mention in your post? |
|
#7
|
|||
|
|||
Re: breaking an infinite loop through stdinQuote:
In case I forgot to mention it: IWFM---YMMV (It Works For Me---Your Mileage May Vary): CPP / C++ / C Code:
Compile "normally": gcc -Wall -W -pedantic test_kbhit_getch.c -o test_kbhit_getch Break out of the loop with ctrl-c or ctrl-d. Output (where I pressed 'a', then esc then c then ctrl-c) Code:
Regards, Dave Footnote: The traditional dos getch() and kbhit() functions do not handle ctrl-c. That is, the program is terminated by the operating system "ungracefully," without allowing the program to handle it and proceed. The functions that I show here allow graceful exit upon detecting ctrl-c. I don't know how to do that with Borland or Microsoft compilers on Windows XP. Then again, I hardly ever need these functions anyhow; it's just an academic exercise as a rebuttal to some who have claimed that certain things "can't be done on Windows," or, "can't be done on Linux," or whatever... |
|
#8
|
|||
|
|||
Re: breaking an infinite loop through stdinWow Dave! That looks interesting....
I don't have much to add except that I found myself wondering about this too a while back while exploring ncurses and win32 console programming. I don't remember if I ended up with a good answer or if it went on the 'another day' heap.... I can't pull anything out of there (the brain) right now.... Anyhow , as has been pointed out there are keyboard modes and, as I remember it (ha), you can set and unset these modes as the situation calls for and can assign ctrl-(x) and alt-(x) combinations to signal certain things etc.. Since your linux, I found good info on ncurses here: http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/ win32 ??? msdn 'knowedge base'..... (yuk on dialup and '9 I think you might find some hints in the right direction. ncurses is nice and fairly easy to implement. It has getch() and just about everything else you could need. (those linux guys...) But, as Dave said, this really gets into another world and you can really get bogged down with 'pretty presentation' issues that last forever.... I needed to build a better foundation first. (and still do!) Howard; |
|
#9
|
|||
|
|||
Re: breaking an infinite loop through stdinQuote:
There have been a number of threads on gidforums with ncurses application information (use the "Search" pull-down thingie). The ncurses library has getch(), but, as far as I know, it does not have kbhit(), which was the subject of the original question. (At least it is one answer to the original question.) However, I seem to recall that you can set no-delay mode on the tty input and then getch() returns ERR if no key has been pressed. This can result in an effective kbhit() function if people are really interested. (In the default mode on the tty input, getch() will wait for a key to be pressed.) Check the documentation. Regards, Dave |
|
#10
|
|||
|
|||
Re: breaking an infinite loop through stdinI remebered something!
In ncurses I WAS forking a child process and then kill()ing it with keystroke or mouseclick in parent. I think I was going to have a dot go back and forth until I pressed (x) which would kill() that child. I forget how successful I was with that though... somewhat , I believe. Then I got a glimpse of using pthreads instead of fork() but didn't go into it much. That seemed the favored route these days. And that was about the extent of ncurses and I went over to learn some win32 console, but haven't done anything with child processes there. Don't know when I might get back to it. Lost in linked lists for the time being! Howard; |
Recent GIDBlog
Vista ?Widgets? on Windows XP by LocalTech
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Text-Based Roulette Game | mfm1983 | C++ Forum | 5 | 29-Nov-2006 12:20 |
| C++ Aparently on infinite loop, but where? | Link | C++ Forum | 7 | 08-Sep-2006 08:40 |
| Array 1 dimensional help please asap | lion123 | C Programming Language | 10 | 18-Feb-2005 21:53 |
| messy loop help please | sammacs | C Programming Language | 6 | 26-Nov-2004 15:18 |
| Nested for loop with function | Tori | C++ Forum | 11 | 08-Nov-2004 13:02 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The