faqcat1d60.html

来自「this is a mirrored site c-faq. thought 」· HTML 代码 · 共 2,607 行 · 第 1/5 页

HTML
2,607
字号
<a name="fupdate"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fupdate.html"><!-- qtag -->Question 12.30</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm trying to update a file in place,by using <TT>fopen</TT> mode <TT>"r+"</TT>,reading a certain string,and writing back a modified string,but it's not working.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Be sure to call <TT>fseek</TT>before you write,bothto seek backto the beginning of the string you're trying to overwrite,andbecausean <TT>fseek</TT> or <TT>fflush</TT>is always required betweenreading and writing in the read/write <TT>"+"</TT> modes.Also, remember that you can only overwrite characterswith the same number of replacementcharacters;there is no way to insert or delete characters in place.Finally,rememberthat overwriting in text modemay truncate the file at that point,and that you may have to preserve line lengths.See also question<a href="faqcatea63.html?sec=osdep#insdelrec">19.14</a>.</p><p>References:ISO Sec. 7.9.5.3<hr><hr><hr><a name="insdelrec"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/insdelrec.html"><!-- qtag -->Question 12.31</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I insert or delete a line(or record)in the middle of a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcatea63.html?sec=osdep#insdelrec">19.14</a>.<hr><hr><hr><a name="fdfilename"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fdfilename.html"><!-- qtag -->Question 12.32</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I recover the file name given an openstream?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcatea63.html?sec=osdep#fdfilename">19.15</a>.<hr><hr><hr><a name="freopen"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/freopen.html"><!-- qtag -->Question 12.33</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I redirect <TT>stdin</TT> or <TT>stdout</TT>to a filefrom within a program?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Use <TT>freopen</TT>.If you're calling a function <TT>f()</TT>which writes to <TT>stdout</TT>,and you want to send its output to a file,and you don't have the option of rewriting <TT>f</TT>,you can use a sequence like:<pre>	freopen(file, "w", stdout);	f();</pre>See, however,question <a href="faqcat1d60.html?sec=stdio#undofreopen">12.34</a>.</p><p>References:ISO Sec. 7.9.5.4<br>H&amp;S Sec. 15.2<hr><hr><hr><a name="undofreopen"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/undofreopen.html"><!-- qtag -->Question 12.34</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Once I've used <TT>freopen</TT>, how can I get the original<TT>stdout</TT>(or <TT>stdin</TT>)back?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There isn't a good way.If you need to switch back,thebest solutionis not tohave used<TT>freopen</TT> in thefirst place.Try using your own explicit output (or input) stream variable,which you can reassign at will, while leaving the original<TT>stdout</TT> (or <TT>stdin</TT>) undisturbed.For example, declare a global<pre>	FILE *ofp;</pre>and replace all calls to <TT>printf( </TT>...<TT> )</TT> with<TT>fprintf(ofp, </TT>...<TT> )</TT>.(Obviously, you'll have to check for calls to<TT>putchar</TT> and <TT>puts</TT>, too.)Then you can set <TT>ofp</TT> to <TT>stdout</TT>orto anything else.</p><p>You might wonder if you could skip <TT>freopen</TT> entirely,and do something like<pre>	FILE *savestdout = stdout;	stdout = fopen(file, "w");	/* WRONG */</pre>leaving yourself able to restore <TT>stdout</TT> later by doing<pre>	stdout = savestdout;		/* WRONG */</pre>but code like this is not likely to work,because <TT>stdout</TT>(and <TT>stdin</TT> and <TT>stderr</TT>)aretypically constants which cannot be reassigned(whichis why <TT>freopen</TT> exists in the first place).</p><p>It may be possible,in a nonportable way,to save awayinformation about a streambeforecalling <TT>freopen</TT>to open some file in its place,such that the original stream can later be restored.The most straightforward and reliable way is to manipulate theunderlying file descriptors using a system-specific call such as<TT>dup</TT>or<TT>dup2</TT>,if available (<a href="../../stdio/rd.kirby.c">example</a>).Another is tocopy or inspect the contents of the<TT>FILE</TT>structure,but this is exceedinglynonportableand unreliable.</p><p>Under some systems,you might be able to reopen a special device file(such as <TT>/dev/fd/1</TT> under modern versions of Unix)which is still attached to (for example) the original standard output.You can,under some systems,explicitly re-open the controlling terminal(see question <a href="faqcat1d60.html?sec=stdio#devtty">12.36</a>),but this isn't necessarily what you want,since theoriginalinput or output(i.e. what <TT>stdin</TT> or <TT>stdout</TT> had beenbefore you called <TT>freopen</TT>)could have been redirectedfrom the command line.</p><p>All of this pertains to stdio redirectioninitially performed by <TT>freopen</TT>,affecting the I/O callswithin the same program that called <TT>freopen</TT>.If what you're trying to do is capture the result of a subprogramexecution,<TT>freopen</TT> probably won't workanyway;see question <a href="faqcatea63.html?sec=osdep#popen">19.30</a> instead.</p><p>Additional links:<a href="../../stdio/sd13.html" rel=subdocument>examples</a><hr><hr><hr><a name="redirp"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/redirp.html"><!-- qtag -->Question 12.35</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I tell if standard input or output is redirected(i.e. whether ``<TT>&lt;</TT>'' or ``<TT>&gt;</TT>''was used on the invocation command line)?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>You can't tell directly,but you can usually look at a few other thingsto make whatever decision you need to.Ifyou wantyour programtotake inputfrom <TT>stdin</TT> when not given any input files,you can do so if <TT>argv</TT> doesn't mention any input files(see question <a href="faqcat38c2.html?sec=misc#argv">20.3</a>),or perhaps if you're given a placeholder like``<TT>-</TT>''instead ofa filename.If you want to suppress promptsif input is not coming from an interactive terminal,on some systems(e.g. Unix, and usually MS-DOS)you can use <TT>isatty(0)</TT> or <TT>isatty(fileno(stdin))</TT>to make the determination.<hr><hr><hr><a name="devtty"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/devtty.html"><!-- qtag -->Question 12.36</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm trying to write a program like ``<TT>more</TT>.''How can Igetbacktothe interactive keyboard if <TT>stdin</TT> is redirected?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There is no portable way of doing this.Under Unix,you can open the special file <TT>/dev/tty</TT>.Under MS-DOS,you can try openingthe ``file'' <TT>CON</TT>,or use routinesor BIOS callssuch as <TT>getch</TT>whichmay go to the keyboardwhether or not input is redirected.<hr><hr><hr><a name="multiway"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/multiway.html"><!-- qtag -->Question 12.36b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I arrange to have output go two places at once,e.g. to the screen and to a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>You can't do this directly,but youcould write your own <TT>printf</TT> variantwhich printed everything twice.Here is a sample <TT>logprintf</TT> functionwhichprints to both <TT>stdout</TT> and a preopened log file:<pre>#include &lt;stdio.h&gt;#include &lt;stdarg.h&gt;extern FILE *logfp;void logprintf(char *fmt, ...){	va_list argp;	va_start(argp, fmt);	vfprintf(stdout, fmt, argp);	va_end(argp);	va_start(argp, fmt);	vfprintf(logfp, fmt, argp);	va_end(argp);}</pre>Now, whenever you call <TT>logprintf</TT>(which you can call with format strings just like <TT>printf</TT>),it prints both to <TT>stdout</TT> and to <TT>logfp</TT>,which you have presumably opened to your desired log file.Another way to arrange this would be<pre>void f2printf(FILE *fp1, FILE *fp2, char *fmt, ...){	va_list argp;	va_start(argp, fmt); vfprintf(fp1, fmt, argp); va_end(argp);	va_start(argp, fmt); vfprintf(fp2, fmt, argp); va_end(argp);}</pre>where <TT>f2printf</TT> is just like <TT>fprintf</TT>except that you give it two file pointers(e.g. <TT>stdout</TT> and <TT>logfp</TT>)and it prints to both of them.</p><p>Both of these techniques obviously require you to use explicitcalls to <TT>logprintf</TT> or <TT>f2printf</TT>.There is no known wayin Standard C to arrange implicitly(i.e. via some call analogous to <TT>freopen</TT>)that one stream,which you print to once with a normal call like <TT>fprintf</TT>,print to two places at once.<a href="../../stdio/functional.html" rel=subdocument>[footnote]</a></p><p>Seealsoquestion <a href="faqcat744e.html?sec=varargs#vprintf">15.5</a>.<hr><hr><hr><a name="binaryio"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/binaryio.html"><!-- qtag -->Question 12.37</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I want toread and write numbersbetween files and memoryin a byte-at-a-time way,not as formatted charactersthe way <TT>fprintf</TT> and <TT>fscanf</TT> do.Howcan I do this?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>What you're trying to do is usually called ``binary'' I/O.First,make sure that you are calling <TT>fopen</TT> with the <TT>"b"</TT> modifier(<TT>"rb"</TT>, <TT>"wb"</TT>, etc.;see question <a href="faqcat1d60.html?sec=stdio#fopenbinary">12.38</a>).Then,use the <TT>&amp;</TT> and <TT>sizeof</TT> operatorstoget a handle onthe sequences of bytesyou are trying to transfer.Usually,the <TT>fread</TT>and <TT>fwrite</TT> functionsare what you want to use;see question <a href="faqcat6b6b.html?sec=struct#io">2.11</a>for an example.</p><p>Note, though,that <TT>fread</TT> and <TT>fwrite</TT> do not necessarily implybinary I/O.If you've opened a file in binary mode,you can use any I/O calls on it(seefor exampletheexamples inquestion <a href="faqcat1d60.html?sec=stdio#extconform">12.42</a>);if you've opened it in text mode,you canuse <TT>fread</TT> or <TT>fwrite</TT> if they're convenient.</p><p>Finally,note that binary data files are not very portable;see question<a href="faqcat38c2.html?sec=misc#binaryfiles">20.5</a>.</p><p>See also question <a href="faqcat1d60.html?sec=stdio#textvsbinary">12.40</a>.<hr><hr><hr><a name="fopenbinary"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fopenbinary.html"><!-- qtag -->Question 12.38</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I read a binary data file properly?I'm occasionally seeing <TT>0x0a</TT> and <TT>0x0d</TT> values getting garbled,andI seemto hit EOF prematurely if the data contains the value <TT>0x1a</TT>.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>When you're reading a binary data file,you shouldspecify <TT>"rb"</TT> modewhen calling <TT>fopen</TT>,to make sure that text file translations do not occur.Similarly,when writing binary data files, use <TT>"wb"</TT>.(Under operating systemssuch as Unixwhich don't distinguish between text and binary files,<TT>"b"</TT>may not be required,but is harmless.)</p><p>Note thatthe text/binary distinction is made when you open the file:once a file is open,it doesn't matter which I/O calls you use on it.See alsoquestions <a href="faqcat1d60.html?sec=stdio#binaryio">12.37</a>, <a href="faqcat1d60.html?sec=stdio#textvsbinary">12.40</a>, <a href="faqcat1d60.html?sec=stdio#extconform">12.42</a>, and <a href="faqcat38c2.html?sec=misc#binaryfiles">20.5</a>.</p><p>References:ISO Sec. 7.9.5.3<br>H&amp;S Sec. 15.2.1 p. 348<hr><hr><hr><a name="stdinbinary"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/stdinbinary.html"><!-- qtag -->Question 12.39</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm writing a``filter''for binary files,but <TT>stdin</TT> and <TT>stdout</TT> are preopenedas text streams.How can I changetheir modeto binary?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There is no standard way to do this.On Unix-like systems,there is no text/binary distinction,sothere is no need to change the mode.Some MS-DOS compilers supply a <TT>setmode</TT> call.Otherwise, you're on your own.<hr><hr><hr><a name="textvsbinary"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/textvsbinary.html"><!-- qtag -->Question 12.40</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's the difference between text and binary I/O?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In text mode,a file is assumed to consist oflines of printable characters(perhaps including tabs).The routines in the stdio library(<TT>getc</TT>, <TT>putc</TT>, and all the rest)translate betweenthe underlying system'send-of-line representationand the single <TT>\n</TT> used in C programs.C programswhich simply read and write texttherefore don't have to worry aboutthe underlying system'snewline conventio

⌨️ 快捷键说明

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