我正在使用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等。
任何人都有任何想法。谢谢你的帮助。
答案 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