2012-11-27 81 views
4

我做了一些研究,以尋找sscanf()的源代碼。但我找不到我的問題的答案。sscanf()是否支持「遞歸」緩衝區?

,當我們以這種方式使用sscanf()

char str[50] = "5,10,15"; 
int x; 
sscanf(str,"%d,%s",&x,str); 

是否sscanf的()支持 「遞歸」 緩衝str

+0

從同一時間讀取和寫入同一個內存區通常不是一個好主意。 –

+0

我知道這一點。但它可以由sscanf函數支持。爲什麼我在尋找。可能是scanf沒有問題。這將允許我優化我的代碼。我將不必添加另一個緩衝區並複製... – MOHAMED

+0

+1不同的問題 –

回答

3

它不會從自我修改緩衝區中斷。但爲了使它(尾)遞歸,你必須讀到字符串的末尾。
的代碼片段:

char str[]="5,10,15"; 
int a[10]={0},x = 0; 
while (sscanf(str,"%d,%s",a+ x++,str)>1); 

讀取所有的整數。

由於這不是真正的遞歸,並且要讀取的字符串不會覆蓋字符串中的asciiz,所以我認爲這是「安全」的含義:只能在家中試用。

+0

巧妙的把戲。顯然效率低於使用%n和循環增加到str的偏移量,這可能是問題的要求,但這是一個好主意。我覺得,你必須以相當愚蠢的方式實施sscanf,因爲這不起作用。 –

1

一般我會建議這個。如果它的作用不是這個意思,那它會在所有的角落案例中。要確定的是,你必須檢查你正在使用的實現的源代碼。如果你希望它是可移植的,那就馬上忘記它,除非你將它看作是一種保證行爲的libc規範。使用strchr()來查找下一個分隔符並更新字符串指針以指向下一個字符。

3

scanf家族函數讀取格式說明符並逐個進行轉換。在您的示例代碼中:

char str[50] = "5,10,15"; 
int x; 
sscanf(str,"%d,%s",&x,str); 

它可能工作,因爲它讀取整數第一個和另一個c字符串。這裏沒有問題,因爲原始str被新值覆蓋。

但考慮以下幾點:

char str[50] = "5 10 15"; 
int x; 
sscanf(str,"%s %d",str, &x); 

它首先從原始值讀取5並覆蓋str,並作爲str年底已因達到隨後的格式說明%d將一無所有從str閱讀終止前%s閱讀。

這只是一個反例,表明這是一個壞主意,並且不起作用。所以你可以說這會在某個時候調用未定義的行爲或者導致其他問題。

+1

同意。即使正確使用,遞歸sscanf()也可能會觸發下一位維護代碼的程序員的所有警報,從而使其重複這種不重要的演繹。尊重你的同事們的時間。保持你的代碼可讀,不要讓他們想! – deStrangis

0

採用strtok()解決的幾乎相同的問題,我,即,使用sscanf()遞歸提取char*的內容(通過的空間的雙重的分離的列表中,例如"1.00 2.01 ...")成一個雙陣列(例如array[1]=1.00array[2]=2.01 ,...)。

下可能會有所幫助,如果我相信我理解你的問題:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 


int main(int argc, char** argv) 
{ 
    char str[]= "5,10,15"; 
    char* token; 

    int x[3]; 

    token = strtok(str, ","); 

    for(int i=0; i<3; i++){ 

      sscanf(token, "%d", &x[i]); 

      token = strtok(NULL, ","); 

    } 

    for(int i=0; i<3; i++) printf("%d\n", x[i]); 

    return 0; 
} 

在運行時,它產生:

5 
10 
15 

strtok()一個有用的說明,請參見http://www.cplusplus.com/reference/cstring/strtok/