2013-07-23 45 views
0

我正在使用Mac OSX並使用bash作爲我的shell。我在C工作,我正在嘗試創建一個文件來重新編號文件。我的代碼的重要組成部分如下:評估字符串中的類型標識符(%d),C

int i; 
for (i=0; i<numberOfFiles; i++) { 
    strcpy(fileName,""); //Set to Null 
    char append[formatLength]; //String being appended 
    sprintf(append,"%%0%dd", formatLength); //example output: %04d 
    strcat(fileName,filePrefix); //Attached Prefix 
    strcat(fileName,append); //Attaches appended part 

    //Missing code: Part which equvaluates %04d as int i, such as 0023. 
} 

這讓我正確的字符串格式我要找(比如formatLength = 4):filePrefix + 04D%。但是,現在我需要評估字符串中的%04d並將其評估爲i,以便文件看起來像:file0001,file0002等。

有沒有人有任何想法。謝謝你的幫助。

+0

所以你需要添加前導零? – Jiminion

+1

或者您需要從file0004中獲得值4?的atoi(* PTR + 4); – Jiminion

+0

所以你希望你的最終結果是這樣的:當'i = 4'時,結果是'filePrefix0004';當'i = 123'時,結果是'filePrefix0123'。那是對的嗎? – wlyles

回答

1

如果我正確理解你的問題,你應該能夠說

char result[(sizeof filePrefix/sizeof (char)) + formatLength]; 
sprintf(result, fileName, i); 

因爲fileName看起來像"filePrefix%04d"。您所需的文件名將被存儲在result中。我不建議將它重新存儲在fileName中,因爲sprintf(fileName, fileName, i)因爲fileName可能太小(例如,當formatLength = 9)。

請注意,您需要(sizeof filePrefix/sizeof (char))找到filePrefix大小(這很可能也char*),然後添加formatLength看到你,

+0

是的,這絕對有效。非常感謝你。 –

+1

'sizeof(char)'總是1,所以'sizeof(filePrefix)+ formatLength'就足夠了。 'char'不需要8位,但是在任何兼容的實現中sizeof(char)都保持爲1。一個與類型無關的表達式應該是'(sizeof(filePrefix)/ sizeof(* filePrefix))+ formatLength' – Clifford

0

的sprintf之後還有多少個字符需要(fileNameString,文件名,我) ; //我認爲你是這個意思,但是使用snprintf()

3

使用你創建的字符串作爲snprintf()的下一個調用的格式字符串。

int formatLength = /* some input */; 
char filePrefix[FILEPREFIX_LEN]; // assigned by some input 
const int FILENAME_LEN = strlen(filePrefix) + formatLength + 1; // +1 for terminating '\0' 
char fileName[FILENAME_LEN]; 

int i; 
for (i=0; i<numberOfFiles; i++) { 
    char temp[TEMPLATE_LEN]; // where TEMPLATE_LEN >= FILEPREFIX_LEN + 3 + number of characters in the decimal representation of formatLength 
    snprintf(temp, TEMPLATE_LEN, "%s%%0%dd", filePrefix, formatLength); 
    // error check snprintf here, in case the destination buffer was not large enough 
    snprintf(fileName, FILENAME_LEN, temp, i); 
    // error check snprintf here, in case the destination buffer was not large enough 

    // use fileName 
} 

因此,如果您filePrefix = 「文件」,那麼你會得到fileName = 「file0001」, 「file0002」, 「file0003」,等等...

雖然很多這樣的工作實際上不是依賴於i,所以你可以在循環外移動它,就像這樣:

int formatLength = /* some input */; 
char filePrefix[FILEPREFIX_LEN]; // assigned by some input 
const int FILENAME_LEN = strlen(filePrefix) + formatLength + 1; // +1 for terminating '\0' 
char fileName[FILENAME_LEN]; 

char temp[TEMPLATE_LEN]; // where TEMPLATE_LEN >= FILEPREFIX_LEN + 3 + number of characters in the decimal representation of formatLength 
snprintf(temp, TEMPLATE_LEN, "%s%%0%dd", filePrefix, formatLength); 
// error check snprintf here, in case the destination buffer was not large enough 

int i; 
for (i=0; i<numberOfFiles; i++) { 
    snprintf(fileName, FILENAME_LEN, temp, i); 
    // error check snprintf here, in case the destination buffer was not large enough 

    // use fileName 
} 

在這些情況下,您的temp(簡稱「模板」,而不是「臨時」)將是「前綴%04d「(例如,前綴長度爲4,filePrefix爲 「字首」)。因此,您需要注意,您的filePrefix不包含任何對printf函數族具有特殊含義的字符。如果你事先知道它不會,那麼你很好。

但是,如果可能的話,那麼你需要做兩件事之一。在使用它之前,您可以通過轉義所有特殊字符來處理filePrefix。在第一snprintf()年初

snprintf(temp, TEMPLATE_LEN, "%%s%%0%dd", formatLength); 
// other stuff... 
snprintf(fileName, FILENAME_LEN, temp, filePrefix, formatLength); 

注意額外%:或者你可以改變你snprintf()調用像這些。這使得模板模式「%s%04d」(例如,對於4的prefixLength),然後在第二次調用時添加filePrefix,以便它的內容不是第二次調用中模式字符串的一部分。

+0

這沒有解決主要問題,即格式字符串是動態的,基於formatLength,可能是4, 5,6等 – Jiminion

+0

謝謝你建議snprintf,但正如@Jim所說,我希望格式長度是動態的。 –

+0

好的,我以前不明白...我會相應地編輯。謝謝。 –

0

你幾乎沒有

// This line could be done before the loop 
sprintf(append,"%%0%dd", formatLength); //example output: %04d 

// Location to store number 
char NumBuffer[20]; 
// Form textual version of number 
sprintf(NumBuffer, append, i); 
strcat(fileName,filePrefix); //Attached Prefix 
strcat(fileName,NumBuffer); //Attaches appended part 
1

您可以構建一個格式字符串,然後把它作爲一個格式字符串格式的另一個電話。請注意,它們的前綴和數字格式說明符可以內置到一個字符串中 - 不需要strcat調用。

鑑於:

snprintf(format_specifier, 
      sizeof(format_specifier), 
      "%s%%0%dd", 
      filePrefix, 
      formatLength) ; // Create format string "<filePrefix>%0<formatLength>", 
          // eg. "file%04d" 

snprintf(fileName,   // Where the filename will be built 
      sizeof(fileName), // The length of the filename buffer 
      format_specifier, // The previously built format string 
      i) ;    // The file number. 

我假定fileName上面是一個數組,如果它是一個指向的數組:

char format_specifier[256] ; 

然後在例如循環代碼可以被替換,那麼sizeof(fileName)將不正確。當然如果你選擇使用sprintf而不是snprintf這是學術。

+0

就像使用'snprintf()'一樣。注意:'formatLength'是'i'文本版本所需的_minimum_空間,它可能需要更多。 – chux

+0

@chux:Doh!我犯了與原始問題中評論的完全相同的錯誤!改爲「相當大」。 – Clifford