在C中评估字符串中的类型标识符(%d)

时间:2013-07-23 18:18:42

标签: c string append

我正在使用Mac OSX并使用bash作为我的shell。我在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等。

任何人都有任何想法。谢谢你的帮助。

5 个答案:

答案 0 :(得分:3)

使用您使用snprintf()创建的字符串作为下次调用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”(例如,对于prefixLength为4和filePrefix为“prefix”)。您需要注意,filePrefix不包含对printf函数族具有特殊含义的任何字符。如果你事先知道它不会,那么你很高兴。

然而,如果有可能,那么你需要做两件事之一。您可以在使用之前处理filePrefix,方法是转义所有特殊字符。或者,您可以将snprintf()来电更改为以下内容:

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

请注意第一个%开头的额外snprintf()。这使得模板模式“%s%04d”(例如,对于prefixLength为4),然后在第二次调用时添加filePrefix,使得它的内容不是第二次调用中模式字符串的一部分。

答案 1 :(得分: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以查看有多少字符需要之后

答案 2 :(得分:1)

您可以构建一个格式字符串,然后将其用作另一个格式化程序调用的格式字符串。请注意,前缀和数字格式说明符可以构建在一个字符串中 - 不需要strcat调用。

假设:

char format_specifier[256] ;

然后您的示例中的循环代码可以替换为:

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是一个数组,如果它是一个指向数组的指针,那么sizeof(fileName)将是不正确的。当然,如果您选择使用sprintf而不是snprintf,那么它就是学术性的。

答案 3 :(得分:0)

sprintf(fileNameString,fileName,i); //我认为你的意思是这个,但是使用snprintf()

答案 4 :(得分: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