[英]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.