① c++ 如何知道sscanf讀取了多少個字元
char str[10];
for (int i = 0; i < 10; i++) str[i] = '!';
執行完後str的值為
str = "!!!!!!!!!!"
我們把str的每個字元都初始化為驚嘆號,當str的值發生變化時,使用printf列印str的值,對比先前的驚嘆號,這樣就可以方便的觀察str發生了怎樣的變化。下面我們做幾個小實驗,看看使用sscanf和正則表達式格式化輸入後,str有什麼變化。
實驗1:
sscanf("123456","%s",str); ---------str的值為 "123456\0!!!"
這個實驗很簡單,把源字元串"123456"拷貝到str的前6個字元,並且把str的第7個字元設為null字元,也就是\0
實驗2:
sscanf("123456","%3s",str); ---------str的值為 "123\0!!!!!!"
看到沒有,正則表達式的百分號後面多了一個3,這告訴sscanf只拷貝3個字元給str,然後把第4個字元設為null字元。
實驗3:
sscanf("aaaAAA","%[a-z]",str); ---------str的值為 "aaa\0!!!!!!"
從這個實驗開始我們會使用正則表達式,括弧裡面的a-z就是一個正則表達式,它可以表示從a到z的任意字元,
在繼續討論之前,我們先來看看百分號表示什麼意思,%表示選擇,%後面的是條件,比如實驗1的"%s",s是一個條件,表示任意字元,"%s"的意思是:只要輸入的東西是一個字元,就把它拷貝給str。實驗2的"%3s"又多了一個條件:只拷貝3個字元。實驗3的「%[a-z]」的條件稍微嚴格一些,輸入的東西不但是字元,還得是一個小寫字母的字元,所以實驗3隻拷貝了小寫字母"aaa"給str,別忘了加上null字元。
實驗4:
sscanf("AAAaaaBBB","%[^a-z]",str); ---------str的值為 "AAA\0!!!!!!"
對於所有字元,只要不是小寫字母,都滿足"^a-z"正則表達式,符號^表示邏輯非。前3個字元都不是小寫字元,所以將其拷貝給str,但最後3個字元也不是小寫字母,為什麼不拷貝給str呢?這是因為當碰到不滿足條件的字元後,sscanf就會停止執行,不再掃描之後的字元。
實驗5:
sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str); ---------段錯誤
這個實驗的本意是:先把大寫字母拷貝給str,然後把小寫字母拷貝給str,但很不幸,程序運行的時候會發生段錯誤,因為當sscanf掃描到字元a時,違反了條件"%[A-Z]",sscanf就停止執行,不再掃描之後的字元,所以第二個條件也就沒有任何意義,這個實驗說明:不能使用%號兩次或兩次以上
實驗6:
sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); ---------str的值為 "aaa\0!!!!!!"
這個實驗出現了一個新的符號:%*,與%相反,%*表示過濾滿足條件的字元,在這個實驗中,%*[A-Z]過濾了所有大寫字母,然後再使用%[a-z]把之後的小寫字母拷貝給str。如果只有%*,沒有%的話,sscanf不會拷貝任何字元到str,這時sscanf的作用僅僅是過濾字元串。
實驗7:
sscanf("AAAaaaBBB","%[a-z]",str); ---------str的值為 "!!!!!!!!!!"
做完前面幾個實驗後,我們都知道sscanf拷貝完成後,還會在str的後面加上一個null字元,但如果沒有一個字元滿足條件,sscanf不會在str 的後面加null字元,str的值依然是10個驚嘆號。這個實驗也說明了,如果不使用%*過濾掉前面不需要的字元,你永遠別想取得中間的字元。
實驗8:
sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); ---------str的值為 "BC\0!!!!!!!"
這是一個綜合實驗,但這個實驗的目的不是幫我們復習前面所學的知識,而是展示兩個值得注意的地方:
注意1:%只能使用一次,但%*可以使用多次,比如在這個實驗裡面,先用%*[A-Z]過濾大寫字母,然後用%*[a-z]過濾小寫字母。
注意2:^後面可以帶多個條件,且這些條件都受^的作用,比如^a-z=表示^a-z且^=(既不是小寫字母,也不是等於號)。
實驗9:
int k;
sscanf("AAA123BBB456", "%*[^0-9]%i", &k); ---------k的值為123
首先,%*[^0-9]過濾前面非數字的字元,然後用%i把數字字元轉換成int型的整數,拷貝到變數k,注意參數必須使用k的地址。
[cpp] view plain
#if 0
1,sscanf():從一個字元串中讀進與指定格式相符的數據.
2,sscanf與scanf類似,都是用於輸入的,只是後者以屏幕(stdin)為輸入源,前者以固定字元串為輸入源。
3,關於正則表達式:
(1)%[..],當字元屬於方括弧里表達式表示的字元集時繼續讀取,否則停止.方括弧里的和正則表達式差不多,^是"排除..."的意思
(2)%*[..],直接跳過方括弧里的字元集並繼續讀取
#endif
#include <iostream>
using namespace std;
int main()
{
char str[10];
for (int i = 0; i < 10; i++) str[i] = '!';
cout<<str<<endl;
sscanf("123456","%s",str);//---------str的值為 "123456\0!!!"
//這個實驗很簡單,把源字元串"123456"拷貝到str的前6個字元,並且把str的第7個字元設為null字元,也就是\0
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("123456","%3s",str); //---------str的值為 "123\0!!!!!!"
//看到沒有,正則表達式的百分號後面多了一個3,這告訴sscanf只拷貝3個字元給str,然後把第4個字元設為null字元。
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("aaaAAA","%[a-z]",str);// ---------str的值為 "aaa\0!!!!!!"
//從這個實驗開始我們會使用正則表達式,括弧裡面的a-z就是一個正則表達式,它可以表示從a到z的任意字元,
//在繼續討論之前,我們先來看看百分號表示什麼意思,%表示選擇,%後面的是條件,比如實驗1的"%s",s是一個條件,表示任意字元,"%s"的意思是:只要輸入的東西是一個字元,就把它拷貝給str。實驗2的"%3s"又多了一個條件:只拷貝3個字元。實驗3的「%[a-z]」的條件稍微嚴格一些,輸入的東西不但是字元,還得是一個小寫字母的字元,所以實驗3隻拷貝了小寫字母"aaa"給str,別忘了加上null字元。
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%[^a-z]",str);// ---------str的值為 "AAA\0!!!!!!"
//對於所有字元,只要不是小寫字母,都滿足"^a-z"正則表達式,符號^表示邏輯非。前3個字元都不是小寫字元,所以將其拷貝給str,但最後3個字元也不是小寫字母,為什麼不拷貝給str呢?這是因為當碰到不滿足條件的字元後,sscanf就會停止執行,不再掃描之後的字元。
cout<<str<<endl;
/*
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str);// ---------段錯誤
//這個實驗的本意是:先把大寫字母拷貝給str,然後把小寫字母拷貝給str,但很不幸,程序運行的時候會發生段錯誤,因為當sscanf掃描到字元a時,違反了條件"%[A-Z]",sscanf就停止執行,不再掃描之後的字元,所以第二個條件也就沒有任何意義,這個實驗說明:不能使用%號兩次或兩次以上
cout<<str<<endl;
*/
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); //---------str的值為 "aaa\0!!!!!!"
//這個實驗出現了一個新的符號:%*,與%相反,%*表示過濾滿足條件的字元,在這個實驗中,%*[A-Z]過濾了所有大寫字母,然後再使用%[a-z]把之後的小寫字母拷貝給str。如果只有%*,沒有%的話,sscanf不會拷貝任何字元到str,這時sscanf的作用僅僅是過濾字元串。
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%[a-z]",str);// ---------str的值為 "!!!!!!!!!!"
//做完前面幾個實驗後,我們都知道sscanf拷貝完成後,還會在str的後面加上一個null字元,但如果沒有一個字元滿足條件,sscanf不會在str 的後面加null字元,str的值依然是10個驚嘆號。這個實驗也說明了,如果不使用%*過濾掉前面不需要的字元,你永遠別想取得中間的字元。
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); //---------str的值為 "BC\0!!!!!!!"
//這是一個綜合實驗,但這個實驗的目的不是幫我們復習前面所學的知識,而是展示兩個值得注意的地方:
//注意1:%只能使用一次,但%*可以使用多次,比如在這個實驗裡面,先用%*[A-Z]過濾大寫字母,然後用%*[a-z]過濾小寫字母。
// 注意2:^後面可以帶多個條件,且這些條件都受^的作用,比如^a-z=表示^a-z且^=(既不是小寫字母,也不是等於號)。
cout<<str<<endl;
for (int i = 0; i < 10; i++) str[i] = '!';
int k;
sscanf("AAA123BBB456", "%*[A-Z]%i", &k); //---------k的值為123
//首先,%*[^0-9]過濾前面非數字的字元,然後用%i把數字字元轉換成int型的整數,拷貝到變數k,注意參數必須使用k的地址。 cout<<str<<endl;
cout<<k<<endl;
return 0;
}
② c語言中關於sscanf函數的運用及%n的用法
代碼如下:
#include<stdio.h>
#include<string.h>
int main (){
char s[200];
int n,wei;
memset(s,0,sizeof(s));
while(gets(s)){
int cnt=0,sum=0,num;
char *p=s;
while(sscanf(p,"%d%n",&n,&wei)==1){
sum+=n;cnt++;wei++;
if(p) p+=wei;
}
printf("%d %d ",cnt,sum);
memset(s,0,sizeof(s));
}
return 0;
}
(2)sscanf如何過濾擴展閱讀
scanf()函數是通用終端格式化輸入函數,它從標准輸入設備(鍵盤) 讀取輸入的信息。可以讀入任何固有類型的數據並自動把數值變換成適當的機內格式。
scanf()函數返回成功賦值的數據項數,出錯時則返回EOF。
其控制串由三類字元構成:
1、格式化說明符;
2、空白符;
3、非空白符;
用空白符結尾時,scanf會跳過空白符去讀下一個字元,所以必須再輸入一個數。這里的空白符包括空格,製表符,換行符,回車符和換頁符。所以如果用scanf("%d ",&a)也會出現同樣的問題。
③ VC++ sscanf 問題
int i = 0, j = 0;
int count = 5;
char buffer1[6] = "12345";
char buffer2[5];
for(count; count > 0; count--)
{
if(buffer1[i] != '3')
{
sscanf(&buffer1[i], "%c", &buffer2[j]);
i++;
j++;
}
else
i++;
}
buffer2[j] = '\0';
④ 一個sscanf的問題
%*[^/]/ 相當於兩步:
1. %*[^/] 不錄入不為/的字元 剩下: /12DDWDFF@122
2. %*/ 不錄入/字元 剩下: 12DDWDFF@122
%[^@]
錄入不為@的字元 取值: 12DDWDFF
⑤ 如何從文本文件中讀取字元串又濾掉空格
簡單
C#的
string str="abc def ght";
List<string> strList=new List<string>();//泛型
string[] strs=str.split(' ');
for(int i=0;i<strs.length;i++)
{
if(strs[i]!="")//過濾且分割
{
strList.add(strs[i]);
}
}
//strList就是你想要的了
⑥ sscanf函數
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、 * 亦可用於格式中, (即 %*d 和 %*s) 加了星號 (*) 表示跳過此數據不讀入. (也就是不把此數據讀入參數中)
2、{a|b|c}表示a,b,c中選一,[d],表示可以有d也可以沒有d。
3、width表示讀取寬度。
4、{h | l | I64 | L}:參數的size,通常h表示單位元組size,I表示2位元組 size,L表示4位元組size(double例外),l64表示8位元組size。
5、type :這就很多了,就是%s,%d之類。
6、特別的:%*[width] [{h | l | I64 | L}]type 表示滿足該條件的被過濾掉,不會向目標參數中寫入值
支持集合操作:
%[a-z] 表示匹配a到z中任意字元,貪婪性(盡可能多的匹配)
%[aB'] 匹配a、B、'中一員,貪婪性
%[^a] 匹配非a的任意字元,貪婪性
例子:
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);
⑦ c++中sscanf函數與sprintf函數的用法
一.sscanf 讀取格式化的字元串中的數據
sscanf和scanf類似,都是用於輸入的,只是後者以屏幕為輸入源,而前者以固定字元串為輸入。
sscanf() 是從一個字元串中讀進與指定格式相符的數據
二.sprintf與printf的用法很類似,只不過是前者輸出到指定的目標,後者輸出到屏幕。
sprintf()指的是字元串格式化命令,主要功能是把格式化的數據寫入某個字元串中。
int scanf(const char format [,agument])
其中format可以是一個或多個
{%[ ][width][{h | l | l64 | L}]}type
{a|b|c}表示a、b、c中選一,[d]表示d是可有可無的。
所以,format形式可以有:
%s
%5s
%[a-z]5d
注意:
%*[width][{h | l | l64 | L}]}type表示過濾滿足條件的字元串,不向目標中輸出。
1、基本用法,取字元串
string source0 = "1234456";
char str[521];
sscanf(source0.c_str(),"%s",str);
sscanf(source0.c_str(),"%4s",str);
2、轉換為整型數
string source0 = "123456";
int x;
sscanf(source0.c_str(),"%d",&x);
sscanf(source0.c_str(),"%3d",&x);
3、停止和范圍
sscanf(source0,"%[^a]",str); //遇到「a」停止
sscanf(source0,"%[^c]",str); //遇到「c」停止
sscanf(source0,"%[1-9A-Z]",str); //只取范圍1-9和A-Z的字元
sscanf(source0,"%[^b-z]",str); //遇到「b-z」停止
sscanf(source0,"%[^c-z]",str); //遇到「c-z」停止
4、格式轉換
char source[512] = "2015:8:1";
int a,b,c;
sscanf(source,"%d:%d:%d",&a,&b,&c);
注意:這個地方a、b、c必須加引用,否則會報錯。
5、復雜情況
char source[512] = "fjkdsjf/123456@fjkdsjf";
char str[512];
sscanf(source,"%*[ /]/%[ @]",str);
結果為:123456
sprintf
sprintf與printf的用法很類似,只不過是前者輸出到指定的目標,後者輸出到屏幕。
int sprintf(char *buffer,const char *format,...)
舉個例子:
結果:
1
buf = 1
buf = 00000001
2
buf = 2
buf = 00000002
⑧ c語言 sscanf(poststr,"m=%[^&]&n=%s",m,n)中的%[^&]是什麼意思
%[^&]的意思是指輸入的數據要遇上&才結束;
比如說在處理字元串中的scanf("%s",a);如果普通的話遇上了空格或者回車就結束了;
但把它改成這個樣子scanf("%[^=]",a);就表示在輸入數據中是以『=』為結束標志的。在遇到空格和回車都不結束當前輸入。
這句話有意思的地方就在於當使用這種特殊結束標志以後,這個標志不但不會被存儲在對應的存儲空間里,而且輸出的時候按照普通方法即可輸出所輸入的字元;
比如我說,我輸入了:
sdfasf asdfasf adf
asf
adsf
fds =
使用printf("%s",a);它就會按照原樣式輸出到』=『前的位置;
⑨ C 語言中怎麼截取字元串的一部分
用指針,再if判斷,將+號前面的提出來放入你自定義的一個字元串中。再用一個if判斷,將+號後面的放入另一個字元串中
⑩ c語言編程,關於sscanf通過中文逗號截取字元串的問題
首先我要大言不慚說一句 在C/C++版塊 折騰文件 字元串 我也是前十名的人物
然後我反駁一下 樓上 sscanf是可以用正則表達式的
接下來 我回答樓主
%[^,] 這樣的結構 ^後面的是單字元
而不是中文的 逗號 是雙位元組的
在C里算是 字元串
因此不能用在這里