[英]C - Using sprintf() to put a prefix inside of a string
我正在尝试使用sprintf()
将字符串“放入自身”,因此可以将其更改为具有整数前缀。 我已经在长度为12的字符数组中对此进行了测试,并且其中已经包含“ Hello World”。
基本前提是我想要一个表示字符串中单词数量的前缀。 因此,我将11个字符复制到长度为12的字符数组中。然后,我尝试通过在函数中使用"%i%s"
来将整数和字符串本身放在后面。 要跳过整数(我不只是将myStr用作%s
的参数),请确保使用myStr + snprintf(NULL, 0, "%i", wordCount)
,它应该是myStr + characters taken up by the integer.
问题是我在执行此操作时会吃掉“ H”并打印“ 2ello World”,而不是在“ Hello World”旁边显示“ 2”
到目前为止,当我尝试将其复制到自身中时,我已经尝试了各种不同的方法来获取字符串中的“过去的整数”,但是似乎没有什么是正确的情况,因为它要么是空字符串,要么只是整数前缀“ 222222222222”本身会复制到整个数组中。
int main() {
char myStr[12];
strcpy(myStr, "Hello World");//11 Characters in length
int wordCount = 2;
//Put the integer wordCount followed by the string myStr (past whatever amount of characters the integer would take up) inside of myStr
sprintf(myStr, "%i%s", wordCount, myStr + snprintf(NULL, 0, "%i", wordCount));
printf("\nChanged myStr '%s'\n", myStr);//Prints '2ello World'
return 0;
}
首先,要将一位数字的前缀插入字符串“ Hello World”中,需要一个13个字符的缓冲区,一个为前缀,11个为“ Hello World”中的字符,另一个为终止的空字符。
其次,不应将缓冲区作为输出缓冲区和输入字符串传递给snprintf
。 当传递给它的对象重叠时,C标准未定义其行为。
下面的程序向您展示如何通过使用memmove
移动字符串来插入前缀。 这主要是教程,因为它通常不是操纵字符串的好方法。 对于短字符串来说,空间不是问题,大多数程序员只会将所需的字符串打印到临时缓冲区中,从而避免出现重叠问题。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Insert a decimal numeral for Prefix into the beginning of String.
Length specifies the total number of bytes available at String.
*/
static void InsertPrefix(char *String, size_t Length, int Prefix)
{
// Find out how many characters the numeral needs.
int CharactersNeeded = snprintf(NULL, 0, "%i", Prefix);
// Find the current string length.
size_t Current = strlen(String);
/* Test whether there is enough space for the prefix, the current string,
and the terminating null character.
*/
if (Length < CharactersNeeded + Current + 1)
{
fprintf(stderr,
"Error, not enough space in string to insert prefix.\n");
exit(EXIT_FAILURE);
}
// Move the string to make room for the prefix.
memmove(String + CharactersNeeded, String, Current + 1);
/* Remember the first character, because snprintf will overwrite it with a
null character.
*/
char Temporary = String[0];
// Write the prefix, including a terminating null character.
snprintf(String, CharactersNeeded + 1, "%i", Prefix);
// Restore the first character of the original string.
String[CharactersNeeded] = Temporary;
}
int main(void)
{
char MyString[13] = "Hello World";
InsertPrefix(MyString, sizeof MyString, 2);
printf("Result = \"%s\".\n", MyString);
}
解决此问题的最佳方法是创建另一个要输出到的缓冲区,然后,如果您确实需要复制回源字符串,则在创建新副本后将其复制回。
如果确实需要,还有其他方法可以“优化”,例如将源字符串放入缓冲区的中间,以便可以为源添加和更改字符串指针(不建议这样做,除非您在嵌入式目标上运行内存有限且缓冲区很大)。 请记住,代码是供人们阅读的,因此最好保持代码整洁且易于阅读。
#define MAX_BUFFER_SIZE 128
int main() {
char srcString[MAX_BUFFER_SIZE];
char destString[MAX_BUFFER_SIZE];
strncpy(srcString, "Hello World", MAX_BUFFER_SIZE);
int wordCount = 2;
snprintf(destString, MAX_BUFFER_SIZE, "%i%s", wordCount, srcString);
printf("Changed string '%s'\n", destString);
// Or if you really want the string put back into srcString then:
strncpy(srcString, destString, MAX_BUFFER_SIZE);
printf("Changed string in source '%s'\n", srcString);
return 0;
}
笔记:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.