📄 faqcat1067.html
字号:
<!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:46 2005 by faqproc version 2.7 --><!-- from source file lib.sgml dated Fri Nov 23 12:45:55 2001 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=lib by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:58:12 GMT --><head><base ><meta name=GENERATOR content="faqproc"><title>Library Functions</title></head><body bgcolor="#ffffff"><H1>13. Library Functions</H1><a name="itoa"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/itoa.html"><!-- qtag -->Question 13.1</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I convert numbers to strings(the opposite of <TT>atoi</TT>)?Is there an <TT>itoa</TT> function?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Just use <TT>sprintf</TT>:<pre> sprintf(string, "%d", number);</pre>(Don't worry that <TT>sprintf</TT> may be overkill,potentially wasting run time or code space;it works well in practice.)Seealsothe examples in the answer to question <a href="faqcatbafd.html?sec=malloc#retaggr">7.5a</a>,andalsoquestions<a href="faqcate107.html?sec=charstring#asciivals">8.6</a>and<a href="faqcat1d60.html?sec=stdio#sprintfsize">12.21</a>.</p><p>You can obviously use <TT>sprintf</TT> to convertlongor floating-point numbers to strings as well(using <TT>%ld</TT> or <TT>%f)</TT>;in other words,<TT>sprintf</TT>can also be thought of asthe opposite of<TT>atol</TT>and <TT>atof</TT>.In addition,you have quite a bit of control over the formatting.(It'sfor these reasonsthatC supplies <TT>sprintf</TT> as a general solution,and not <TT>itoa</TT>.)</p><p>If you simply must write an <TT>itoa</TT> function,here are some things to consider:<UL><li>There is asample implementation in K&R.<li>You'll have to worry aboutreturn buffer allocation;see question <a href="faqcatbafd.html?sec=malloc#retaggr">7.5a</a>.<li>A naïve implementation usuallydoesn'thandle the most-negative integer(INT_MIN, usually -32,768 or -2,147,483,648)properly.</UL></p><p>See also questions <a href="faqcat1d60.html?sec=stdio#sprintfsize">12.21</a> and <a href="faqcat38c2.html?sec=misc#hexio">20.10</a>.</p><p>References:K&R1 Sec. 3.6 p. 60<br>K&R2 Sec. 3.6 p. 64<hr><hr><hr><a name="strncpy"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/strncpy.html"><!-- qtag -->Question 13.2</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why does <TT>strncpy</TT> not alwaysplace a <TT>'\0'</TT> terminatorin the destination string?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font><TT>strncpy</TT>was first designed to handle a now-obsolete data structure,the fixed-length, not-necessarily-<TT>\0</TT>-terminated``string.''<a href="../../lib/strncpyexamp.html" rel=subdocument>[footnote]</a><TT>strncpy</TT> is admittedly a bit cumbersome to use in other contexts,since you must often append a<TT>'\0'</TT> to the destinationstring by hand.</p><p>You can get around the problem by using <TT>strncat</TT>instead of <TT>strncpy</TT>.Ifthe destination string starts out empty(that is, if you do<TT>*dest = '\0'</TT>first),<TT>strncat</TT> does what you probably wanted <TT>strncpy</TT> to do:<pre> *dest = '\0'; strncat(dest, source, n);</pre>This code copies up to <TT>n</TT> characters,and always appends a <TT>\0</TT>.</p><p>Another possibility is<pre><TT>sprintf(dest, "%.*s", n, source)</TT></pre>(though,strictly speaking,this is only guaranteed to work for <TT>n</TT> <= 509).</p><p>Whenarbitrarybytes(as opposed to strings)are being copied,<TT>memcpy</TT> is usually a more appropriate function to usethan <TT>strncpy</TT>.<hr><hr><hr><a name="substr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/substr.html"><!-- qtag -->Question 13.3</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Does C have anything like the ``substr''(extract substring)routine present in other languages?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Not as such.(Onereason it doesn'tis that,as mentioned inquestion <a href="faqcatbafd.html?sec=malloc#malloc2">7.2</a>andsection <a href="faqcate107.html?sec=charstring#index">8</a>,C has no managed string type.)</p><p>To extract a substring of length <TT>LEN</TT>starting at index <TT>POS</TT> in a source string,use something like<pre> char dest[LEN+1]; strncpy(dest, &source[POS], LEN); dest[LEN] = '\0'; /* ensure \0 termination */</pre>or,using the trick fromquestion <a href="faqcat1067.html?sec=lib#strncpy">13.2</a>,<pre> char dest[LEN+1] = ""; strncat(dest, &source[POS], LEN);</pre>or,making use of pointer instead of array notation,<pre> strncat(dest, source + POS, LEN);</pre>(The expression <TT>source + POS</TT> is,by definition,identical to <TT>&source[POS]</TT>--seealsosection <a href="faqcatca65.html?sec=aryptr#index">6</a>.)<hr><hr><hr><a name="strupper"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/strupper.html"><!-- qtag -->Question 13.4</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How do I convert a string to all upper or lower case?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Some libraries have routines<TT>strupr</TT> and <TT>strlwr</TT>or<TT>strupper</TT> and <TT>strlower</TT>,but these are not Standard or portable.It's a straightforward exerciseto write upper/lower-case functionsin terms of the<TT>toupper</TT> and <TT>tolower</TT>macros in <TT><ctype.h></TT>;see also question <a href="faqcat1067.html?sec=lib#toupper">13.5</a>.(The only tricky part isthatthefunctionwill either have to modify the string in-placeordeal with the problem of returning a new string;see question <a href="faqcatbafd.html?sec=malloc#retaggr">7.5a</a>.)</p><p>(Notealsothat converting characters and strings to upper or lower case isvastly more complicated when multinational character sets arebeingused.)</p><p>References:K&R1 Sec. 2.7 p. 40<br>K&R2 Sec. 2.7 p. 43<hr><hr><hr><a name="toupper"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/toupper.html"><!-- qtag -->Question 13.5</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Whydo some versions of<TT>toupper</TT> act strangely if given an upper-case letter?<br>Why does some code call <TT>islower</TT> before <TT>toupper</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In earlier times,<TT>toupper</TT>was afunction-likepreprocessor macroandwas defined to work only onlower-case letters;itmisbehavedif applied to digits, punctuation,or letters which were already upper-case.Similarly,<TT>tolower</TT>worked only on upper-case letters.Therefore,old code(or code writtenfor wide portability)tends to call<TT>islower</TT> before <TT>toupper</TT>,and<TT>isupper</TT> before <TT>tolower</TT>.</p><p>The C Standard, however,says that <TT>toupper</TT> and <TT>tolower</TT>must work correctly on all characters,i.e. characterswhich don't need changingareleftalone.</p><p>References:ISO Sec. 7.3.2<br>H&S Sec. 12.9 pp. 320-1<br>PCS p. 182<hr><hr><hr><a name="strtok"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/strtok.html"><!-- qtag -->Question 13.6</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I split up astringintowhitespace-separated fields?<br>How can I duplicate the processby which <TT>main()</TT>is handed <TT>argc</TT> and <TT>argv</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The only Standard functionavailableforthis kind of``tokenizing''is<TT>strtok</TT>,although it can be tricky to use<a href="../../lib/strtokstate.html" rel=subdocument>[footnote]</a>and it may not do everything you want it to.(For instance, it does not handle quoting.)Here is a usage example,which simply prints each field as it's extracted:<pre>#include <stdio.h>#include <string.h>char string[] = "this is a test"; /* not char *; see Q <a href="faqcat5e04.html?sec=strangeprob#strlitnomod">16.6</a> */char *p;for(p = strtok(string, " \t\n"); p != NULL; p = strtok(NULL, " \t\n")) printf("\"%s\"\n", p);</pre></p><p>As an alternative,here is a routine I usefor building an <TT>argv</TT> all at once:<pre>#include <ctype.h>int makeargv(char *string, char *argv[], int argvsize){ char *p = string; int i; int argc = 0; for(i = 0; i < argvsize; i++) { /* skip leading whitespace */ while(isspace(*p)) p++; if(*p != '\0') argv[argc++] = p; else { argv[argc] = 0; break; } /* scan over arg */ while(*p != '\0' && !isspace(*p)) p++; /* terminate arg: */ if(*p != '\0' && i < argvsize-1) *p++ = '\0'; } return argc;}</pre></p><p>Calling <TT>makeargv</TT> is straightforward:<pre> char *av[10]; int i, ac = makeargv(string, av, 10); for(i = 0; i < ac; i++) printf("\"%s\"\n", av[i]);</pre></p><p>If you want each separator character to be significant,for instance if you want two tabs in a row to indicate an omitted field,it's probablymore straightforwardto use <TT>strchr</TT>:<pre>#include <stdio.h>#include <string.h>char string[] = "this\thas\t\tmissing\tfield";char *p = string;while(1) { /* break in middle */ char *p2 = strchr(p, '\t'); if(p2 != NULL) *p2 = '\0'; printf("\"%s\"\n", p); if(p2 == NULL) break; p = p2 + 1;}</pre></p><p>All thecode fragmentspresented heremodify theinput string,by inserting<TT>\0</TT>'sto terminate each field(meaning that the string must be writable;see question <a href="faqcatd3c2.html?sec=decl#strlitinit">1.32</a>).If you'll need the original string later,make a copy before breaking it up.</p><p>References:K&R2 Sec. B3 p. 250<br>ISO Sec. 7.11.5.8<br>H&S Sec. 13.7 pp. 333-4<br>PCS p. 178<hr><hr><hr><a name="regex"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../lib/regex.html"><!-- qtag -->Question 13.7</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I need some code to doregular expressionandwildcard matching.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Make sure yourecognizethedifference between:</p><UL><li>Classicregular expressions,variants of which are used in such Unix utilities as<TT>ed</TT> and <TT>grep</TT>.In regular expressions,a dot <TT>.</TT> usually matches any single character,and the sequence <TT>.*</TT> usually matches any string of characters.(Of course,full-blownregular expressions have several more featuresthanthese two.)<li>Filenamewildcards,variants of which are used by most operating systems.There is considerably more variationhere(in particular,MS-DOS wildcards aresomewhat stunted),but it is often the case that<TT>?</TT> matches any single character,and <TT>*</TT> matches any string of characters.</UL><p>There are a number of packages available for matching regular expressions.Most packages use a pair of functions,one for ``compiling'' the regular expression,and one for ``executing'' it(i.e. matching strings against it).Look for header files named <TT><regex.h></TT>or <TT><regexp.h></TT>,and functions called<TT>regcmp</TT>/<TT>regex</TT>,<TT>regcomp</TT>/<TT>regexec</TT>,or<TT>re_comp</TT>/<TT>re_exec</TT>.(These functions mayexistin a separate regexp library.)A popular,freely-redistributableregexp packageby Henry Spencer is available fromftp.cs.toronto.edu in pub/regexp.shar.Zor in several other archives.The GNU project has apackagecalled rx.<a href="../../lib/offload.html" rel=subdocument>[footnote]</a>See also question <a href="faqcatccbd.html?sec=resources#sources">18.16</a>.</p><p>Filename wildcard matching(sometimes called``globbing'')isdonein a variety of ways ondifferentsystems.On Unix,wildcards are automatically expanded by the shellbefore a process is invoked,so programs rarely have to worry about them explicitly.Under MS-DOS compilers,there is often a special object filewhich can be linked into a programtoexpand wildcardswhile <TT>argv</TT> is being built.Several systems(including MS-DOS and VMS)providesystem services forlisting or opening files specified by wildcards.Check your compiler/library documentation.See also questions<a href="faqcatea63.html?sec=osdep#readdir">19.20</a>and<a href="faqcat38c2.html?sec=misc#argv">20.3</a>.</p><p>Here is a quick little wildcard matcher by Arjan Kenter:<pre>int match(char *pat, char *str){ switch(*pat) { case '\0': return !*str; case '*': return match(pat+1, str) || *str && match(pat, str+1); case '?': return *str && match(pat+1, str+1); default: return *pat == *str && match(pat+1, str+1); }}</pre>(Copyright1995,Arjan Kenter)</p><p>With this definition,the call <TT>match("a*b.c", "aplomb.c")</TT>would return 1.</p><p>References:Schumacher, ed., <I>Software Solutions in C</I> Sec. 3 pp. 35-71<hr><hr><hr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -