閱讀102 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Linux下常用C語言字符串操作函數

stroul,
strdup
snprintf()
atio
 
C中常用字符串操作函數
#include <string.h>
 
size_t strlen(const char *s)   測量字符串長度s的實際長度。
例如s[20]="abc",那麼strlen(s)的結果是3,而不是20.這就是實際長度
 
char *strcat(const char *s1, const *s2)    將字符串s2連接到s1的尾部。從s1的/0開始。
 
int strcmp(const *s1,const *s2)  比較s1和s2。
s1 = s2的時候返回值 =0
s1 < s2的時候返回至 <0
s1 > s2的時候返回值 >0
 
char *strchr(const char *s, char c);  返回s中首次出現C的位置的指針。如果s中不存在c則返回NULL
 
char *strrchr(const char *s, char c );返回s中最後一次出現c的位置的指針。如果沒有,則返回0
 
char *strstr(const char *haystack, const char *needle);返回haystack中needle字符串首次出現的位置的指針(不比較結束符NULL)。若果沒找到則返回NULL
 
 
限定長度的比較,拷貝和追加函數
int strncmp(char *s1, const char *s2, size_t n);(這些都是針對字符串的前n個字符來操作的)
 
char *strncpy(char *dest, const char *src, size_t n);
 
char *strncat(char *dest, const char *src, size_t n);
 
char *strdup(char *s)返回指向被複製的字符串的指針,所需空間由malloc()分配而且需要free釋放空間
 
int atoi(const char *nptr);將字符串轉換成整型數
atoi()會掃描參數nptr字符串,跳過前麵的空格,直到遇上數字或者正負號才開始裝換,而再遇到非數字或者非字符串結束時('/0')
其實ato是一族將字符轉換為數的函數,atof,atol:他們分別是將字符串轉換成浮點型,長整型數。
 
 
unsigned long int stroul(const char *nptr, char **endptr, int base);
stroul() 會根據base所指定的進製(10代表進製,18代表16進製)將字符串nptr轉換成無符號的長整形數,base的範圍是 2~36,或者是0.當base的值為0時則是采用10進製做轉換,當遇到'0x'開頭的字符則會使用16進製做轉換。一開始stroul()會掃描參數 nptr字符串,跳過前麵的空格字符串,直到遇上數字或者正負號才開始轉換,在遇到非數字或者字符串結束'/0'時結束轉換,並將結果返回。若參數 endptr不為NULL,則會將遇到不合條件而終止的nptr的字符串指針由endptr返回。
stroul()返回轉換後的長整形,否則返回ERANGE並將錯誤代碼存入errno中。
ERANGE指定的轉換字符串超出合法返回。
 
int snprintf(char *restrict buf, size_t n, const char *restrict format,...)
snprintf()最多從源串format中拷貝n-1個字符到目標串buf中,然後再在後麵加一個'/0'.如果目標串的大小為n的話,將不會溢出。
snprintf()如果成功則返回存入數組的字符數,若錯誤則返回負值。
例程:

#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { char str[5]; char s="linux is powerful!" snprintf(str,5,s); printf("str = %s", str); }

運行結果

str = linu

 

int sprintf(char *buf, char *format,arg_list);

sprintf() 是一個功能強大的函數。跟printf(char *format,arg_list)的功能類似。不過,printf()是將格式化的字符輸出到屏幕,而sprintf()則是將格式化的字符放入到 buf中。這個函數對操作緩衝區buf,並對其內容加以格式帶來了極大的方便。

例如:

#include <stdio.h> #include <string.h> char *buf; char *a = "linux"; char *b = "is"; char *c = "powerful"; sprintf(buf, "Hello:%s %s %s", a, b, c); printf("%s",buf);

輸出結果為:

Hello:linux is powerful

tips:

strlen()和strcat()是兩個比較耗時的操作。在程序中應該少使用。

在自己編寫函數是遇到char型的定義中,如果這個char 參數在傳入後不會被修改,應該在前麵加const

例如  a(const char *s);s字符串在傳入後內容不會被修改。則前麵要加const.

 

關於const char *p和char const *p的關係

可以根據讀音來區分。

const char *p

p is point to const char ;

char const *p

p is a const point  to char;

#include <stdio.h> int rename( const char *oldfname, const char *newfname ); 用於更改文件名

 

sscanf() - 從一個字符串中讀進與指定格式相符的數據.
  函數原型:
  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
  int scanf( const char *format [,argument]... );
  說明:
  sscanf與scanf類似,都是用於輸入的,隻是後者以屏幕(stdin)為輸入源,前者以固定字符串為輸入源。
  其中的format可以是一個或多個 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '/t' | '/n' | 非%符號}

1. 常見用法。
  char buf[512] = ;
  sscanf("123456 ", "%s", buf);
  printf("%s/n", buf);
  結果為:123456
  2. 取指定長度的字符串。如在下例中,取最大長度為4字節的字符串。
  sscanf("123456 ", "%4s", buf);
  printf("%s/n", buf);
  結果為:1234
  3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。
  sscanf("123456 abcdedf", "%[^ ]", buf);
  printf("%s/n", buf);
  結果為:123456
  4. 取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。
  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
  printf("%s/n", buf);
  結果為:123456abcdedf
  5. 取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。
  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
  printf("%s/n", buf);
  結果為:123456abcdedf
  6、給定一個字符串iios/12DDWDFF@122,獲取 / 和 @ 之間的字符串,先將 "iios/"過濾掉,再將非'@'的一串內容送到buf中
  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
  printf("%s/n", buf);
  結果為:12DDWDFF
  7、給定一個字符串““hello, world”,僅保留world。(注意:“,”之後有一空格)
  sscanf(“hello, world”, "%*s%s", buf);
  printf("%s/n", buf);
  結果為:world
  %*s表示第一個匹配到的%s被過濾掉,即hello被過濾了
  如果沒有空格則結果為NULL。
  sscanf的功能很類似於正則表達式, 但卻沒有正則表達式強大,所以如果對於比較複雜的字符串處理,建議使用正則表達式.
  //-------------------------------------------------------
  sscanf,表示從字符串中格式化輸入
  上麵表示從str中,輸入數字給x,就是32700
  久以前,我以為c沒有自己的split string函數,後來我發現了sscanf;一直以來,我以為sscanf隻能以空格來界定字符串,現在我發現我錯了。
  sscanf是一個運行時函數,原形很簡單:
  int sscanf(
  const char *buffer,
  const char *format [,
  argument ] ...
  );
  它強大的功能體現在對format的支持上。
  我以前用它來分隔類似這樣的字符串2006:03:18:
  int a, b, c;
  sscanf("2006:03:18", "%d:%d:%d", a, b, c);
  以及2006:03:18 - 2006:04:18:
  char sztime1[16] = "", sztime2[16] = "";
  sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2);
  但是後來,我需要處理2006:03:18-2006:04:18
  僅僅是取消了‘-’兩邊的空格,卻打破了%s對字符串的界定。
  我需要重新設計一個函數來處理這樣的情況?這並不複雜,但是,為了使所有的代碼都有統一的風格,我需要改動很多地方,把已有的sscanf替換成我自己的分割函數。我以為我肯定需要這樣做,並伴隨著對sscanf的強烈不滿而入睡;一覺醒來,發現其實不必。
  format-type中有%[]這樣的type field。如果讀取的字符串,不是以空格來分隔的話,就可以使用%[]。
  %[]類似於一個正則表達式。[a-z]表示讀取a-z的所有字符,[^a-z]表示讀取除a-z以外的所有字符。
  所以那個問題也就迎刃而解了:
  sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);

 

strftime()

strftime() 函數將時間格式化
我們可以使用strftime()函數將時間格式化為我們想要的格式。它的原型如下:
size_t strftime(
     char *strDest,
     size_t maxsize,
     const char *format,
     const struct tm *timeptr
);
我們可以根據format指向字符串中格式命令把timeptr中保存的時間信息放在strDest指向的字符串中,最多向strDest中存放maxsize個字符。該函數返回向strDest指向的字符串中放置的字符數。
函數strftime()的操作有些類似於sprintf():識別以百分號(%)開始的格式命令集合,格式化輸出結果放在一個字符串中。格式化命令說明串 strDest中各種日期和時間信息的確切表示方法。格式串中的其他字符原樣放進串中。格式命令列在下麵,它們是區分大小寫的。
%a 星期幾的簡寫
%A 星期幾的全稱
%b 月分的簡寫
%B 月份的全稱
%c 標準的日期的時間串
%C 年份的後兩位數字
%d 十進製表示的每月的第幾天
%D 月/天/年
%e 在兩字符域中,十進製表示的每月的第幾天
%F 年-月-日
%g 年份的後兩位數字,使用基於周的年
%G 年分,使用基於周的年
%h 簡寫的月份名
%H 24小時製的小時
%I 12小時製的小時
%j 十進製表示的每年的第幾天
%m 十進製表示的月份
%M 十時製表示的分鍾數
%n 新行符
%p 本地的AM或PM的等價顯示
%r 12小時的時間
%R 顯示小時和分鍾:hh:mm
%S 十進製的秒數

(未完待續)

最後更新:2017-04-02 04:01:46

  上一篇:go WI-FI
  下一篇:go 嵌入式arm linux藍牙文件傳輸移植