📄 library_5.html
字号:
<P>The return value is the length of the entire transformed string. Thisvalue is not affected by the value of <VAR>size</VAR>, but if it is greaterthan <VAR>size</VAR>, it means that the transformed string did not entirelyfit in the array <VAR>to</VAR>. In this case, only as much of the string asactually fits was stored. To get the whole transformed string, call<CODE>strxfrm</CODE> again with a bigger output array.<P>The transformed string may be longer than the original string, and itmay also be shorter.<P>If <VAR>size</VAR> is zero, no characters are stored in <VAR>to</VAR>. In thiscase, <CODE>strxfrm</CODE> simply returns the number of characters that wouldbe the length of the transformed string. This is useful for determiningwhat size string to allocate. It does not matter what <VAR>to</VAR> is if<VAR>size</VAR> is zero; <VAR>to</VAR> may even be a null pointer.<P>Here is an example of how you can use <CODE>strxfrm</CODE> whenyou plan to do many comparisons. It does the same thing as the previousexample, but much faster, because it has to transform each string onlyonce, no matter how many times it is compared with other strings. Eventhe time needed to allocate and free storage is much less than the timewe save, when there are many strings.<P><PRE>struct sorter { char *input; char *transformed; };/* This is the comparison function used with <CODE>qsort</CODE> to sort an array of <CODE>struct sorter</CODE>. */intcompare_elements (struct sorter *p1, struct sorter *p2){ return strcmp (p1->transformed, p2->transformed);}/* This is the entry point--the function to sort strings using the locale's collating sequence. */voidsort_strings_fast (char **array, int nstrings){ struct sorter temp_array[nstrings]; int i; /* Set up <CODE>temp_array</CODE>. Each element contains one input string and its transformed string. */ for (i = 0; i < nstrings; i++) { size_t length = strlen (array[i]) * 2; temp_array[i].input = array[i]; /* Transform <CODE>array[i]</CODE>. First try a buffer probably big enough. */ while (1) { char *transformed = (char *) xmalloc (length); if (strxfrm (transformed, array[i], length) < length) { temp_array[i].transformed = transformed; break; } /* Try again with a bigger buffer. */ free (transformed); length *= 2; } } /* Sort <CODE>temp_array</CODE> by comparing transformed strings. */ qsort (temp_array, sizeof (struct sorter), nstrings, compare_elements); /* Put the elements back in the permanent array in their sorted order. */ for (i = 0; i < nstrings; i++) array[i] = temp_array[i].input; /* Free the strings we allocated. */ for (i = 0; i < nstrings; i++) free (temp_array[i].transformed);}</PRE><P><STRONG>Compatibility Note:</STRONG> The string collation functions are a newfeature of ANSI C. Older C dialects have no equivalent feature.<P><H2><A NAME="SEC64" HREF="library_toc.html#SEC64" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC64">Search Functions</A></H2><P>This section describes library functions which perform various kindsof searching operations on strings and arrays. These functions aredeclared in the header file <TT>`string.h'</TT>.<A NAME="IDX315"></A><A NAME="IDX316"></A><A NAME="IDX314"></A><P><A NAME="IDX317"></A><U>Function:</U> void * <B>memchr</B> <I>(const void *<VAR>block</VAR>, int <VAR>c</VAR>, size_t <VAR>size</VAR>)</I><P>This function finds the first occurrence of the byte <VAR>c</VAR> (convertedto an <CODE>unsigned char</CODE>) in the initial <VAR>size</VAR> bytes of theobject beginning at <VAR>block</VAR>. The return value is a pointer to thelocated byte, or a null pointer if no match was found.<P><A NAME="IDX318"></A><U>Function:</U> char * <B>strchr</B> <I>(const char *<VAR>string</VAR>, int <VAR>c</VAR>)</I><P>The <CODE>strchr</CODE> function finds the first occurrence of the character<VAR>c</VAR> (converted to a <CODE>char</CODE>) in the null-terminated stringbeginning at <VAR>string</VAR>. The return value is a pointer to the locatedcharacter, or a null pointer if no match was found.<P>For example,<PRE>strchr ("hello, world", 'l') => "llo, world"strchr ("hello, world", '?') => NULL</PRE><P>The terminating null character is considered to be part of the string,so you can use this function get a pointer to the end of a string byspecifying a null character as the value of the <VAR>c</VAR> argument.<P><A NAME="IDX319"></A><U>Function:</U> char * <B>strrchr</B> <I>(const char *<VAR>string</VAR>, int <VAR>c</VAR>)</I><P>The function <CODE>strrchr</CODE> is like <CODE>strchr</CODE>, except that it searchesbackwards from the end of the string <VAR>string</VAR> (instead of forwardsfrom the front).<P>For example,<PRE>strrchr ("hello, world", 'l') => "ld"</PRE><P><A NAME="IDX320"></A><U>Function:</U> char * <B>strstr</B> <I>(const char *<VAR>haystack</VAR>, const char *<VAR>needle</VAR>)</I><P>This is like <CODE>strchr</CODE>, except that it searches <VAR>haystack</VAR> for asubstring <VAR>needle</VAR> rather than just a single character. Itreturns a pointer into the string <VAR>haystack</VAR> that is the firstcharacter of the substring, or a null pointer if no match was found. If<VAR>needle</VAR> is an empty string, the function returns <VAR>haystack</VAR>.<P>For example,<PRE>strstr ("hello, world", "l") => "llo, world"strstr ("hello, world", "wo") => "world"</PRE><P><A NAME="IDX321"></A><U>Function:</U> void * <B>memmem</B> <I>(const void *<VAR>needle</VAR>, size_t <VAR>needle_len</VAR>,<BR>const void *<VAR>haystack</VAR>, size_t <VAR>haystack_len</VAR>)</I><P>This is like <CODE>strstr</CODE>, but <VAR>needle</VAR> and <VAR>haystack</VAR> are bytearrays rather than null-terminated strings. <VAR>needle_len</VAR> is thelength of <VAR>needle</VAR> and <VAR>haystack_len</VAR> is the length of<VAR>haystack</VAR>.<P>This function is a GNU extension.<P><A NAME="IDX322"></A><U>Function:</U> size_t <B>strspn</B> <I>(const char *<VAR>string</VAR>, const char *<VAR>skipset</VAR>)</I><P>The <CODE>strspn</CODE> ("string span") function returns the length of theinitial substring of <VAR>string</VAR> that consists entirely of characters thatare members of the set specified by the string <VAR>skipset</VAR>. The orderof the characters in <VAR>skipset</VAR> is not important.<P>For example,<PRE>strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz") => 5</PRE><P><A NAME="IDX323"></A><U>Function:</U> size_t <B>strcspn</B> <I>(const char *<VAR>string</VAR>, const char *<VAR>stopset</VAR>)</I><P>The <CODE>strcspn</CODE> ("string complement span") function returns the lengthof the initial substring of <VAR>string</VAR> that consists entirely of charactersthat are <EM>not</EM> members of the set specified by the string <VAR>stopset</VAR>.(In other words, it returns the offset of the first character in <VAR>string</VAR>that is a member of the set <VAR>stopset</VAR>.)<P>For example,<PRE>strcspn ("hello, world", " \t\n,.;!?") => 5</PRE><P><A NAME="IDX324"></A><U>Function:</U> char * <B>strpbrk</B> <I>(const char *<VAR>string</VAR>, const char *<VAR>stopset</VAR>)</I><P>The <CODE>strpbrk</CODE> ("string pointer break") function is related to<CODE>strcspn</CODE>, except that it returns a pointer to the first characterin <VAR>string</VAR> that is a member of the set <VAR>stopset</VAR> instead of thelength of the initial substring. It returns a null pointer if no suchcharacter from <VAR>stopset</VAR> is found.<P>For example,<P><PRE>strpbrk ("hello, world", " \t\n,.;!?") => ", world"</PRE><P><H2><A NAME="SEC65" HREF="library_toc.html#SEC65" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC65">Finding Tokens in a String</A></H2><P><A NAME="IDX325"></A><A NAME="IDX326"></A><A NAME="IDX327"></A><P>It's fairly common for programs to have a need to do some simple kindsof lexical analysis and parsing, such as splitting a command string upinto tokens. You can do this with the <CODE>strtok</CODE> function, declaredin the header file <TT>`string.h'</TT>.<A NAME="IDX328"></A><P><A NAME="IDX329"></A><U>Function:</U> char * <B>strtok</B> <I>(char *<VAR>newstring</VAR>, const char *<VAR>delimiters</VAR>)</I><P>A string can be split into tokens by making a series of calls to thefunction <CODE>strtok</CODE>.<P>The string to be split up is passed as the <VAR>newstring</VAR> argument onthe first call only. The <CODE>strtok</CODE> function uses this to set upsome internal state information. Subsequent calls to get additionaltokens from the same string are indicated by passing a null pointer asthe <VAR>newstring</VAR> argument. Calling <CODE>strtok</CODE> with anothernon-null <VAR>newstring</VAR> argument reinitializes the state information.It is guaranteed that no other library function ever calls <CODE>strtok</CODE>behind your back (which would mess up this internal state information).<P>The <VAR>delimiters</VAR> argument is a string that specifies a set of delimitersthat may surround the token being extracted. All the initial charactersthat are members of this set are discarded. The first character that is<EM>not</EM> a member of this set of delimiters marks the beginning of thenext token. The end of the token is found by looking for the nextcharacter that is a member of the delimiter set. This character in theoriginal string <VAR>newstring</VAR> is overwritten by a null character, and thepointer to the beginning of the token in <VAR>newstring</VAR> is returned.<P>On the next call to <CODE>strtok</CODE>, the searching begins at the nextcharacter beyond the one that marked the end of the previous token.Note that the set of delimiters <VAR>delimiters</VAR> do not have to be thesame on every call in a series of calls to <CODE>strtok</CODE>.<P>If the end of the string <VAR>newstring</VAR> is reached, or if the remainder ofstring consists only of delimiter characters, <CODE>strtok</CODE> returnsa null pointer.<P><STRONG>Warning:</STRONG> Since <CODE>strtok</CODE> alters the string it is parsing,you always copy the string to a temporary buffer before parsing it with<CODE>strtok</CODE>. If you allow <CODE>strtok</CODE> to modify a string that camefrom another part of your program, you are asking for trouble; thatstring may be part of a data structure that could be used for otherpurposes during the parsing, when alteration by <CODE>strtok</CODE> makes thedata structure temporarily inaccurate.<P>The string that you are operating on might even be a constant. Thenwhen <CODE>strtok</CODE> tries to modify it, your program will get a fatalsignal for writing in read-only memory. See section <A HREF="library_21.html#SEC336" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC336">Program Error Signals</A>.<P>This is a special case of a general principle: if a part of a programdoes not have as its purpose the modification of a certain datastructure, then it is error-prone to modify the data structuretemporarily.<P>The function <CODE>strtok</CODE> is not reentrant. See section <A HREF="library_21.html#SEC357" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC357">Signal Handling and Nonreentrant Functions</A>, fora discussion of where and why reentrancy is important.<P>Here is a simple example showing the use of <CODE>strtok</CODE>.<P><PRE>#include <string.h>#include <stddef.h>...char string[] = "words separated by spaces -- and, punctuation!";const char delimiters[] = " .,;:!-";char *token;...token = strtok (string, delimiters); /* token => "words" */token = strtok (NULL, delimiters); /* token => "separated" */token = strtok (NULL, delimiters); /* token => "by" */token = strtok (NULL, delimiters); /* token => "spaces" */token = strtok (NULL, delimiters); /* token => "and" */token = strtok (NULL, delimiters); /* token => "punctuation" */token = strtok (NULL, delimiters); /* token => NULL */</PRE><P>Go to the <A HREF="library_4.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_4.html">previous</A>, <A HREF="library_6.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_6.html">next</A> section.<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -