C/C++ 字符串處理總結

xmnx 9年前發布 | 16K 次閱讀 C/C++開發 C/C++

string 和 char* 的互相轉換

通常情況下,用 string 操作會更加的方便,這里是std::string的相關函數。由 char* 轉 string 非常的方便,直接賦值或者用std::string的構造函數,詳見這里learncpp.com 。由 string 轉 char* 一般有兩種辦法:(1) 利用std::string::copy()函數;(2) 先用std::string::c_str()把string 轉為 const char*, 然后利用strcpy()函數拷貝到 char* 中。一個例子如下:

#include <iostream>

include <string>

using namespace std;

int main() { string str = "Hello, world!"; char ps[20]; // ps[] 某種程度類似于 cons char strcpy(ps, str.c_str()); // str.c_str() 返回值 const char ps[str.length()] = '\0'; // 或者 *(ps + str.length()) = 0;

char *p = (char*)malloc(20);
str.copy(p, str.length(), 0);   // 可以指定區間,前閉后開
p[str.length()] = '\0';         // 字符'\0' 就是 0

cout << ps << endl << p << endl;
free(p);

char* h = "freedom";
string h2(h);                  // 或者 string h2 = h;
cout << h2 << endl;

return 0;

}</pre>

char* 和 int, float 等的格式化轉換

從字符串中提取指定類型數字或子串,這種情形也是非常的常見。大部分的情形都可以用sscanf()sprintf() 這兩個函數來實現,如果要求復雜,那么就用正則庫或自己手寫自動機。一個例子如下:

#include <iostream>

include <string>

include<stdio.h>

int main() { // 從字符串中提取數字 char* p = "192.168.1.1"; int a[4]; sscanf(p, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); std::cout << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << "\n";

// 從字符串中提取數字,指定的字符串
char* p2 = "170 60 Alice";
int height, weight;
char name[20];
sscanf(p2, "%d %d %s", &height, &weight, name);
std::cout << name << " height: " << height << " weight: " << weight << "\n";

// 浮點型數字轉字符串,并四舍五入保留指定位數小數
double pi = 3.1415;
char str[50];
sprintf(str, "%s %.3f", "pi is:", pi);
std::cout << str << "\n";  // 輸出 3.142

return 0;

}</pre>

介紹一下 format 參數的用法,int sscanf ( const char * s, const char * format, ...);,其中參數 format 的用法和 scanf() 函數中用法是一樣的。和正則表達式有那么一點點的類似。
format可為一個或多個{%[*][width][{h|l|L}]type|''|'\t'|'\n'|非%符號}格式轉換符。集合中{a|b|c}表示格式符a、b、c任選其一。以中括號括起來的格式符可選。%與type為必選,所有格式符必須以%開頭。一些規則:

  • 賦值抑制符*表明按照隨后的轉換符指示來讀取輸入,但將其丟棄不予賦值(跳過)。抑制符無需相應的指針可變參數,該轉換也不計入函數返回的成功賦值次數。%*[width][{h|l|L}]type表示滿足該條件的字符被過濾掉,不會向目標參數中賦值。
  • width表示最大讀取寬度。當讀入字符數超過該值,或遇到不匹配的字符時,停止讀取。多數轉換丟棄起始的空白字符。這些被丟棄的字符及轉換結果添加的空結束符'\0'均不計入最大讀取寬度。
  • {h|l|L}為類型修飾符。h 指示輸入的數字數值以 short int 或 unsigned short int類型存儲;hh 指示輸入以 signed char 或 unsigned char 類型存儲。l(小寫L) 指示輸入以 long int、unsigned long int 或 double 類型存儲,若與 %c 或 %s 結合則指示輸入以寬字符或寬字符串存儲;ll 等同 L。L指示輸入以long long類型存儲。
  • type為類型轉換符,如 %s、%d 。
  • </ul>

    此外還有字符集合規則,有點兒像正則表達式:

    • %[]:字符集合。[]表示指定的字符集合匹配非空的字符序列;^則表示過濾。該操作不會跳過空白字符(空格、制表或換行符),因此可用于目標字符串不以空白字符分隔時。[]內可有一到多個非^字符(含連字符-),且無順序要求。%[a-z]表示匹配a到z之間的任意字符,%[aB-]匹配a、B、-中的任一字符;
    • %[^a]則匹配非a的任意字符,即獲取第一個a之前的(不為a的)所有字符。^可作用于多個條件,如^a-z=表示 ^a-z且^=(既非小寫字母亦非等號)。使用[]時接收輸入的參數必須是有足夠存儲空間的 char、signed char 或unsigned char數組。[] 也是轉換符,故 %[] 后無 s。
    • n:至此已讀入值(未必賦值)的等價字符數,該數目必須以 int 類型存儲,并不是很常用。
    • </ul>

      舉例:

      源字符串 format 匹配后
      hello %s hello
      hello, world %s hello,
      hello, world %[a-z] hello
      12345helloWORLD %*[1-9]%[a-z] hello
      IpAddr=10.46.44.40 %*[^=]=%s 10.46.44.40
      email:wxy@zte.com.cn %*[^:]:%s wxy@zte.com.cn
 本文由用戶 xmnx 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!