⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 faqcatea63.html

📁 this is a mirrored site c-faq. thought might need offline
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN"><!-- This collection of hypertext pages is Copyright 1995-2005 by Steve Summit. --><!-- Content from the book "C Programming FAQs: Frequently Asked Questions" --><!-- (Addison-Wesley, 1995, ISBN 0-201-84519-9) is made available here by --><!-- permission of the author and the publisher as a service to the community. --><!-- It is intended to complement the use of the published text --><!-- and is protected by international copyright laws. --><!-- The on-line content may be accessed freely for personal use --><!-- but may not be published or retransmitted without explicit permission. --><!-- --><!-- this page built Sat Dec 24 21:47:47 2005 by faqproc version 2.7 --><!-- from source file osdep.sgml dated Sat Nov 24 11:09:52 2001 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=osdep by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:58:26 GMT --><head><base ><meta name=GENERATOR content="faqproc"><title>System Dependencies</title></head><body bgcolor="#ffffff"><H1>19. System Dependencies</H1><a name="cbreak"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../osdep/cbreak.html"><!-- qtag -->Question 19.1</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I read a single character from the keyboard withoutwaiting forthe RETURN key?How can I stop characters from beingechoedon the screen as they're typed?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Alas,there is no standard or portable way to dothese thingsin C.Concepts such as screensand keyboards are not even mentionedin the Standard,which deals only with simple I/O ``streams''of characters.</p><p>Input to a computer programtypicallypasses through several stages.At the lowest level,device-dependent routineswithin the operating systemhandle the details of interfacing with particular devicessuch as keyboards, serial lines, disk drives, etc.Above that,modern operating systems tend to havea device-independent I/O layer,unifying accessto any file or device.Finally,a C program is usually insulatedfrom the operating system's I/O facilitiesby the portable functions of the stdio library.</p><p>At some level,interactive keyboard input is usuallycollected and presented to the requesting programa line at a time.This gives the operating system a chanceto support input line editing(backspace/delete/rubout, etc.)in a consistent way,without requiring that itbe built into every program.Only when the user is satisfied and presses the RETURN key(or equivalent)is the line made available to the calling program.Even if the calling program appears to be reading inputa character at a time(with <TT>getchar</TT> or the like),the first callblocks until the user has typed an entire line,at which point potentially manycharacters become availableand many character requests(e.g. <TT>getchar</TT> calls)are satisfied in quick succession.</p><p>When a program wants toread each character immediately as it arrives,itscourse of actionwill depend onwhere in the input stream the line collectionis happeningand how it can be disabled.Under some systems(e.g. MS-DOS, VMS in some modes),a program can usea differentor modifiedset of OS-level input callsto bypass line-at-a-time input processing.Under other systems(e.g. Unix, VMS in other modes),the part of the operating system responsible for serial input(often called the ``terminal driver'')must be placed in a mode whichturns offline-at-a-time processing,after whichall calls tothe usual input routines(e.g. <TT>read</TT>,<TT>getchar</TT>, etc.)will return characters immediately.Finally,a fewsystems(particularly older, batch-oriented mainframes)perform input processinginperipheral processors which cannot be toldto do anything other than line-at-a-time input.</p><p>Therefore,when you need to do character-at-a-time input(or disable keyboard echo,whichis an analogous problem),you willhave to use a techniquespecific to the system you're using,assumingit provides one.Since comp.lang.c is oriented towards those topicsthat the C language hasdefined support for,you will usually get better answers to other questions by referring to a system-specific newsgroupsuch ascomp.unix.questionsorcomp.os.msdos.programmer,and to the FAQ lists for these groups.Note that the answersmay differ even across variantsof otherwise similar systems(e.g. across different variants of Unix);bear in mind when answering system-specific questions that theanswer that applies to your system may not apply to everyone else's.</p><p>However, since these questions arefrequently asked here,herearebrief answersfor somecommonsituations.</p><p>Depending onwhich operating system you're usingandwhat libraries you have available,you may be able to use one(or more!)of the following techniques:</p><UL><li>If you can use the ``curses'' library,you can call <TT>cbreak</TT><a href="../../osdep/crmode.html" rel=subdocument>[footnote]</a>(and perhaps <TT>noecho</TT>),after which calls to <TT>getch</TT>will return characters immediately.<li>If all you're trying to do isread a short password without echo,youmay be able touse a function called <TT>getpass</TT>,if it's available.(Another possibility for hiding typed passwordsis to select black characters on a black background.)<li>Under``classic''versions ofUnix,use <TT>ioctl</TT>and the TIOCGETP and TIOCSETP(or TIOCSETN) requestson file descriptor 0to manipulatethesgttyb structure,defined in <TT>&lt;sgtty.h&gt;</TT>and documented in tty(4).In the <TT>sg_flags</TT> field,set the CBREAK(or RAW) bit,and perhaps clear the ECHO bit.<li>Under System V Unix,use <TT>ioctl</TT>and the TCGETAW and TCSETAW requestson file descriptor 0to manipulatethetermio structure,defined in <TT>&lt;termio.h&gt;</TT>.In the <TT>c_lflag</TT> field,clear the ICANON(and perhaps ECHO)bits.Also,set<TT>c_cc[VMIN]</TT> to 1 and <TT>c_cc[VTIME]</TT> to 0.<li>Under any operating system(Unix or otherwise)offering POSIX compatibility,use the <TT>tcgetattr</TT> and <TT>tcsetattr</TT> callson file descriptor 0to manipulatethetermios structure,defined in <TT>&lt;termios.h&gt;</TT>.In the<TT>c_lflag</TT> field,clear the ICANON(and perhaps ECHO)bits.Also,set<TT>c_cc[VMIN]</TT> to 1 and <TT>c_cc[VTIME]</TT> to 0.<li>In a pinch,under Unix,use <TT>system</TT>(see question <a href="faqcatea63.html?sec=osdep#system">19.27</a>)to invoke the <TT>stty</TT> commandto set terminal drivermodes(as in the preceding three items).<li>UnderMS-DOS,use <TT>getch</TT>or <TT>getche</TT>,or the correspondingBIOS interrupts.<li>Under VMS,try theScreen Management (SMG$) routines,or curses,or issue low-level $QIO'swith the IO$_READVBLKfunction code(and perhaps IO$M_NOECHO, and others)to ask for one character at a time.(It's also possible to set character-at-a-timeor ``pass through'' modes in the VMS terminal driver.)<li>Under other operating systems, you're on your own.</UL><p></p><p>(As an aside,note thatsimplyusing <TT>setbuf</TT> or <TT>setvbuf</TT>to set <TT>stdin</TT> to unbufferedwill <em>not</em> generally serve to allow character-at-a-time input.)</p><p>If you change terminal modes,savea copythe initial stateand be sure to restore it no matter how your program terminates.</p><p>If you're trying to write a portable program,a good approach is to define your own suite of three functions to(1)set theterminal driverorinput systeminto character-at-a-time mode(if necessary),(2)get characters,and(3)return the terminal driverto its initial statewhen the program is finished.(Ideally, such a set of functionsmightbe part of the C Standard, some day.)</p><p>As an example,here is a tiny test programwhich prints the decimal valuesof the next ten charactersas they are typed,without waiting for RETURN.It iswritten in terms of three functions,as described,and isfollowed by implementations of the three functionsfor curses,classic Unix,System V Unix,and MS-DOS.(The on-line archives associated with this listcontain amore complete set of functions.)<pre>#include &lt;stdio.h&gt;main(){	int i;	if(tty_break() != 0)		return 1;	for(i = 0; i &lt; 10; i++)		printf(" = %d\n", tty_getchar());	tty_fix();	return 0;}</pre></p><p>This implementationof the three functionsis for curses:<pre>#include &lt;curses.h&gt;int tty_break(){	initscr();	cbreak();	return 0;}int tty_getchar(){	return getch();}int tty_fix(){	endwin();	return 0;}</pre></p><p>Here is the codefor ``classic'' (V7, BSD) Unix:<pre>#include &lt;stdio.h&gt;#include &lt;sgtty.h&gt;static struct sgttyb savemodes;static int havemodes = 0;int tty_break(){	struct sgttyb modmodes;	if(ioctl(fileno(stdin), TIOCGETP, &amp;savemodes) &lt; 0)		return -1;	havemodes = 1;	modmodes = savemodes;	modmodes.sg_flags |= CBREAK;	return ioctl(fileno(stdin), TIOCSETN, &amp;modmodes);}int tty_getchar(){	return getchar();}int tty_fix(){	if(!havemodes)		return 0;	return ioctl(fileno(stdin), TIOCSETN, &amp;savemodes);}</pre></p><p>The code for System V Unixis similar:<pre>#include &lt;stdio.h&gt;#include &lt;termio.h&gt;static struct termio savemodes;static int havemodes = 0;int tty_break(){	struct termio modmodes;	if(ioctl(fileno(stdin), TCGETA, &amp;savemodes) &lt; 0)		return -1;	havemodes = 1;	modmodes = savemodes;	modmodes.c_lflag &amp;= ~ICANON;	modmodes.c_cc[VMIN] = 1;	modmodes.c_cc[VTIME] = 0;	return ioctl(fileno(stdin), TCSETAW, &amp;modmodes);}int tty_getchar(){	return getchar();}int tty_fix(){	if(!havemodes)		return 0;	return ioctl(fileno(stdin), TCSETAW, &amp;savemodes);}</pre></p><p>Finally,here is animplementation for MS-DOS:<pre>int tty_break() { return 0; }int tty_getchar(){	return getche();}int tty_fix() { return 0; }</pre></p><p>Turning off echois left as an exercise for the reader.</p><p>For detailed information onterminal(keyboard and screen)I/Oprogramming,see an FAQ list, book,or documentation set specific to your operating system.(Note thatthere can be many more details to take care of,e.g. special characters to disableas well asmore mode bits to toggle,thanwere mentionedabove.)</p><p>See also question <a href="faqcatea63.html?sec=osdep#readavail">19.2</a>.</p><p>Additional links:<a href="../../osdep/sd20.html" rel=subdocument>more solutions</a></p><p>References:PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1<br>POSIX Sec. 7<hr><hr><hr><a name="readavail"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../osdep/readavail.html"><!-- qtag -->Question 19.2</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I find outif there are charactersavailable for reading(and if so, how many)?Alternatively, how can I do a read that will not block if thereare no characters available?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>These, too, are entirely operating-system-specific.Some versions of curses have a <TT>nodelay</TT> function.Depending on your system, you may also be able to use``nonblocking I/O'', or a system call named<TT>select</TT>or <TT>poll</TT>,or theFIONREADioctl,or<TT>c_cc[VTIME]</TT>,or <TT>kbhit</TT>,or <TT>rdchk</TT>,or theO_NDELAYoption to <TT>open</TT> or <TT>fcntl</TT>.You can also try setting an alarmto cause a blocking read to time out after a certain interval(under Unix,look at <TT>alarm</TT>,<TT>signal</TT>,and maybe <TT>setitimer</TT>).</p><p>If what you're trying to do is read input from several sources without blocking,you will definitely want to use some kind of a ``select'' call,because a busy-wait, polling loop isterribly inefficienton a multitasking system.</p><p>See also question <a href="faqcatea63.html?sec=osdep#cbreak">19.1</a>.<hr><hr><hr><a name="baton"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../osdep/baton.html"><!-- qtag -->Question 19.3</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I display apercentage-done indicationthat updates itself in place,or show one of those``twirling baton''progress indicators?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>These simple things, at least, you can do fairly portably.Printingthecharacter <TT>'\r'</TT>will usually give you

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -