📄 faqcatea63.html
字号:
<p><font face=Helvetica size=8 color=blue><b>A:</b></font>There is no portable way.Under some versions of Unixyou can call <TT>statfs</TT>.Under MS-DOS,use interrupt 0x21 subfunction 0x36,or perhaps a routine such as<TT>diskfree</TT>.Another possibility is to use<TT>popen</TT>(see question <a href="faqcatea63.html?sec=osdep#popen">19.30</a>)to invoke and read the output of a ``disk free'' command(<TT>df</TT> on Unix).</p><p>(Note that the amount of free space apparently available on a diskmay not match thesize of the largest fileyou can store,for all sorts of reasons.)<hr><hr><hr><a name="readdir"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/readdir.html"><!-- qtag -->Question 19.20</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I read a directory in a C program?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See if you can usethe<TT>opendir</TT> and <TT>readdir</TT>functions,which arepart of the POSIX standardand areavailable on mostUnixvariants.Implementations also exist forMS-DOS,VMS,and other systems.(MS-DOS also hasFINDFIRST and FINDNEXTroutineswhich doessentially the same thing,andMS Windows has<TT>FindFirstFile</TT> and <TT>FindNextFile</TT>.)<TT>readdir</TT>returns just thefile names;if you need more information about the file,try calling <TT>stat</TT>.To match filenames to some wildcard pattern,see question <a href="faqcat1067.html?sec=lib#regex">13.7</a>.</p><p>Here is a tiny example which lists the files in the current directory:<pre>#include <stdio.h>#include <sys/types.h>#include <dirent.h>main(){ struct dirent *dp; DIR *dfd = opendir("."); if(dfd != NULL) { while((dp = readdir(dfd)) != NULL) printf("%s\n", dp->d_name); closedir(dfd); } return 0;}</pre>(On older systems, the header file to <TT>#include</TT> may be <TT><direct.h></TT> or <TT><dir.h></TT>,and the pointer returned by <TT>readdir</TT> may be a <TT>struct direct *</TT>.This example assumes that <TT>"."</TT> is a synonym for the current directory.)</p><p>In a pinch, you could use<TT>popen</TT>(see question <a href="faqcatea63.html?sec=osdep#popen">19.30</a>)to call an operating system list-directory program,and read its output.(If you only need the filenames displayed to the user,you could conceivably use <TT>system</TT>;see question <a href="faqcatea63.html?sec=osdep#system">19.27</a>.)</p><p>References:K&R2 Sec. 8.6 pp. 179-184<br>PCS Sec. 13 pp. 230-1<br>POSIX Sec. 5.1<br>Schumacher, ed., <I>Software Solutions in C</I> Sec. 8<hr><hr><hr><a name="mkdir"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/mkdir.html"><!-- qtag -->Question 19.21</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How do I create a directory?<br>How do I remove a directory(and its contents)?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>If your operating system supportsthese services,they arelikely to beprovidedin Cviafunctionsnamed<TT>mkdir</TT> and<TT>rmdir</TT>.Removing a directory's contents as well will require listing them(see question <a href="faqcatea63.html?sec=osdep#readdir">19.20</a>)and calling <TT>remove</TT>(see also question <a href="faqcatea63.html?sec=osdep#delete">19.16</a>).If you don't have these C functionsavailable,try <TT>system</TT>(see question <a href="faqcatea63.html?sec=osdep#system">19.27</a>)alongwithyour operating system's delete command(s).</p><p>References:PCS Sec. 12 pp. 203-4<br>POSIX Secs. 5.4.1,5.5.2<hr><hr><hr><a name="memavail"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/memavail.html"><!-- qtag -->Question 19.22</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I find out how much memory is available?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Your operating system may provide a routine which returns this information,but it's quite system-dependent.(Also, the number may vary over time.)If you're trying to predict whetheryou'll be able toallocatea certain amount of memory,just try it--call<TT>malloc</TT>(requesting that amount)and checkthereturn value.<hr><hr><hr><a name="bigdatastr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/bigdatastr.html"><!-- qtag -->Question 19.23</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I allocate arrays or structures bigger than 64K?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>A reasonablecomputerought togive you transparent accessto all available memory.If you'renot so lucky,you'll either have to rethink your program's use of memory,or use various system-specific techniques.</p><p>64K is(still)a prettybig chunk of memory.No matter how much memory your computerhas available,it's asking a lot to be able to allocate huge amounts ofitcontiguously.(The C Standard does not guarantee thatsingle objects can be 32K or larger,or 64K for C99.)Often it's a good idea to use datastructures which don't require that all memory be contiguous.For dynamically-allocated multidimensional arrays,you canuse pointers to pointers,as illustrated inquestions <a href="faqcatca65.html?sec=aryptr#dynmuldimary">6.16</a> and <a href="faqcat38c2.html?sec=misc#ragged">20.2</a>.Instead of a large array of structures,you can use a linked list,or an array of pointers to structures.</p><p>If you're using aPC-compatible(8086-based)system,and running up against a64K or640K limit,consider using``huge'' memory model,or expanded or extendedmemory,or malloc variants such as <TT>halloc</TT>or <TT>farmalloc</TT>,or a 32-bit``flat'' compiler(e.g. djgpp,see question <a href="faqcatccbd.html?sec=resources#compilers">18.3</a>),or some kind of a DOS extender,or another operating system.</p><p>References:ISO Sec. 5.2.4.1<br>C9X Sec. 5.2.4.1<hr><hr><hr><a name="dgroup"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/dgroup.html"><!-- qtag -->Question 19.24</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What does the error message``DGROUPdata allocationexceeds 64K''mean,and what can I do about it?I thought that using large model meant that I could usemore than 64K of data!</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Even in large memory models,MS-DOS compilers apparently toss certain data(strings, some initialized global or <TT>static</TT> variables)into a default data segment,and it's this segment that is overflowing.Either use less global data,or,if you're already limiting yourself to reasonable amounts(and if the problem is due to something like the number of strings),you may be able to coax the compilerinto not using the default data segment for so much.Some compilers place only ``small'' data objectsin the default data segment,and give you a way(e.g. the <TT>/Gt</TT> option under Microsoft compilers)to configure the threshold for ``small.''<hr><hr><hr><a name="rawmemadr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/rawmemadr.html"><!-- qtag -->Question 19.25</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I access memory(a memory-mapped device,or graphics memory)located at a certain address?<br>How can I do PEEK and POKE in C?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Set a pointer,of the appropriate type,to the right number(using an explicit castto assure the compilerthat you really do intend this nonportable conversion):<pre> unsigned int *magicloc = (unsigned int *)0x12345678;</pre>Then, <TT>*magicloc</TT> refers to the location you want.<a href="../../osdep/fn92.html" rel=subdocument>[footnote]</a>If the location is a memory-mapped I/O register,you will probably also want to usethe <TT>volatile</TT> qualifier:``<TT>volatile unsigned int *magicloc</TT>''.(If you want to refer to a byte at a certain addressrather than a word,use <TT>unsigned char *</TT>.)</p><p>UnderMS-DOS,you may find a macro like <TT>MK_FP()</TT>handyfor working with segments andoffsets.As suggested by Gary Blaine,you can also declare tricky array pointers which allow you to access screen memory using arraynotation.For example,on an MS-DOS machinein an 80x25 text mode,given the declaration<pre>unsigned short (far * videomem)[80] = (unsigned short (far *)[80])0xb8000000;</pre>you can access the character and attribute byteat row <TT>i</TT>, column <TT>j</TT>with <TT>videomem[i][j]</TT>.</p><p>Manyoperating systems execute user-mode programsin a protected modewhere direct access to I/O devices(or to <em>any</em> address outside the running process)is simply not possible.In such cases youwillhave to ask the operating systemto carry out I/O operations for you.</p><p>See also questions<a href="faqcatabdc.html?sec=ptrs#int2ptr">4.14</a>and<a href="faqcat1f1a.html?sec=null#accessloc0">5.19</a>.</p><p>References:K&R1 Sec. A14.4 p. 210<br>K&R2 Sec. A6.6 p. 199<br>ISO Sec. 6.3.4<br>Rationale Sec. 3.3.4<br>H&S Sec. 6.2.7 pp. 171-2<hr><hr><hr><a name="endiantest"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/endiantest.html"><!-- qtag -->Question 19.25b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I determine whether a machine'sbyte orderis big-endian or little-endian?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcat38c2.html?sec=misc#endiantest">20.9</a>.<hr><hr><hr><a name="accessloc0"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/accessloc0.html"><!-- qtag -->Question 19.26</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I accessan interrupt vectorlocated atthe machine's location 0?If I set a pointer to <TT>0</TT>,the compiler might translate it to some nonzero internal nullpointer value.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcat1f1a.html?sec=null#accessloc0">5.19</a>.<hr><hr><hr><a name="system"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/system.html"><!-- qtag -->Question 19.27</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I invokeanother program(a standalone executable,or an operating system command)from within a C program?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Usethe library function<TT>system</TT>,which does exactly that.</p><p>Some systems also provide a family of <TT>spawn</TT>routines which accomplishapproximately the same thing.<TT>system</TT> is more ``portable''in that it is required under the ANSI C Standard,although the interpretation of the commandstring--itssyntax and the set of commandsaccepted--willobviously vary tremendously.</p><p>The<TT>system</TT>function``calls''a command in the manner of a subroutine,and controleventuallyreturns to the calling program.If you want to overlay the calling program with another program(that is,a ``chain'' operation)you'll need asystem-specific routine,such as the <TT>exec</TT> family on Unix.</p><p>Notethat <TT>system</TT>'s return valueisat bestthe command's exit status(although even that is not guaranteed),and usually has nothing to do with the output of the command.</p><p>See alsoquestions<a href="faqcatea63.html?sec=osdep#system2">19.28</a>and<a href="faqcatea63.html?sec=osdep#popen">19.30</a>.</p><p>References:K&R1 Sec. 7.9 p. 157<br>K&R2 Sec. 7.8.4 p. 167, Sec. B6 p. 253<br>ISO Sec. 7.10.4.5<br>H&S Sec. 19.2 p. 407<br>PCS Sec. 11 p. 179<hr><hr><hr><a name="system2"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/system2.html"><!-- qtag -->Question 19.28</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I call <TT>system</TT> when parameters(filenames, etc.)of the executed commandaren't known until run time?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Just use <TT>sprintf</TT>(or perhaps <TT>strcpy</TT> and <TT>strcat</TT>)to build the command string in abuffer,then call <TT>system</TT> with that buffer.(Make sure the buffer is allocated with enough space;see also questions <a href="faqcatbafd.html?sec=malloc#malloc2">7.2</a> and <a href="faqcat1d60.html?sec=stdio#sprintfsize">12.21</a>.)</p><p>Here isa contrived examplesuggesting how you mightbuild a data file,then sort it(assuming the existence of a sort utility,and Unix-or MS-DOS-styleinput/output redirection):<pre> char *datafile = "file.dat"; char *sortedfile = "file.sort"; char cmdbuf[50]; FILE *fp = fopen(datafile, "w"); /* ...write to fp to build data file... */ fclose(fp); sprintf(cmdbuf, "sort < %s > %s", datafile, sortedfile); system(cmdbuf); fp = fopen(sortedfile, "r"); /* ...now read sorted data from fp... */</pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -