2016-07-04 70 views
0

我是新在C編碼,並編寫一個程序,需要創建一個從0增加爲使自定義文件名的文件名,我用sprintf()來連接,像這樣的計數器和文件擴展名:C - sprintf()如何工作?

int main(void) 
{ 
    // do stuff 
    int count = 0; 
    while (condition == true) 
    { 
     char filename[7]; 
     sprintf(filename, "0%02d.txt", count) //count goes up to a max of 50; 
     count++; 

     //check condition 
    } 
    return 0; 
} 

然而,每一個

sprintf(filename, "0%02d.txt", count); 

運行,計數被重置爲0

我的問題的時間,這是什麼的sprintf()做算?爲什麼在傳遞給sprintf()後計數會改變?

任何幫助將不勝感激。

編輯:對不起,我沒有在我的問題的代碼太清楚 - 我寫的程序上的在線課程的鍛鍊,次數上升到50。一個最大我現在已經改變了我的代碼以反映這一點。此外,謝謝你告訴我大約%04D,我用的是一個複雜的if語句來確定有多少個零添加到我的名,使其3位。

+2

定義變量count的位置在哪裏?沒有足夠的上下文來知道「count」存在和可能被設置的位置。 – lit

+0

'sprintf'不會改變'count'。但是你的意思是'filename'的長度。對於'count'的大值,它會溢出 - *這*可能會破壞實際代碼中的count。將其設置爲足夠大以容納* any *'int'值,再加上字符串終止符。 「count」的3位數字只有足夠的空間。 –

+0

'condition'定義在哪裏? while(condition == true)'似乎永遠不會循環或永遠循環。 – chux

回答

1

儘管問題的標題,這與sprintf()無關,這可能按預期工作,但所有與count

如果計數是一個全局變量(即以外的任何功能),那麼它應該保持函數調用之間的其值。所以這可能並非如此。

如果它是一個局部變量(函數內聲明的),那麼它可以有任何價值,因爲這些失去其價值函數結束時,當函數被再次運行沒有得到初始化。它可以始終爲0,但在不同的情況下,它可以是其他的東西。換句話說,該值或多或少不確定。

有一個本地變量保持函數調用之間的值,使之靜。

static int count = 0; 

但請注意,當您再次停止並再次運行程序時,它將再次從0開始。這意味着你可能會覆蓋000.txt,然後001.txt

如果你真的想避免重複的文件名,你將不得不更加複雜,看看哪些文件已經存在,確定最高的數字,並增加那一個。所以你不使用變量,你檢查已經存在的文件。這是更多的工作,但是避免用這種編號文件名覆蓋現有文件的唯一可靠方法。


FWIW,我會使用類似"00%04d.txt"作爲格式字符串,所以你得到的文件000000.txt000001.txt等看起來比000.txt一個按照字母順序排列的文件列表更好,001.txt0010.txt0011.txt002.txt等。他們也更容易解析他們的號碼。

作爲風向標注意到,務必使你的緩衝區更大一點,例如

char filename[20]; 

緩衝區太小是一個問題。一個太大的不是,除非它很大並且破壞了堆棧。20個字符的風險非常小。

+0

你的例子溢出了'char filename [10];' –

+0

啊,是的,對不起。更新。我太習慣Delphi的自動字符串了。 –

1

我認爲這可能是sprintf。 「0%02d.txt」是7個字符。字符串末尾的空值將會出現在下一個位置,這可能是堆棧中的計數。在一個小型機器(x86)上,這可能意味着在每個sprintf()中計數的底部字節被清零。

正如其他人所說。使文件名緩衝區更大。