簡體   English   中英

sprintf和char []與字符串

[英]sprintf and char [] vs. string

我需要將const char *傳遞給函數。 在通過它之前,我通常需要根據一些變量來構建它。 我永遠無法確定哪種方法更優雅,總體上更好:

  • 分配足夠長的數組以適合文本,並使用sprintf構建最終變量並將其傳遞給函數。
  • 使用+運算符(並置)使用變量初始化字符串s ,然后使用s.c_str()將其傳遞給函數。

使用數組的缺點:可能不適合整個文本。
優點:快。

使用字符串的缺點:我不必擔心易於構建的內存管理。 優點:慢。

我的第二個問題是:通常如何從其他變量字符串構建完整的字符串?

除非絕對對性能至關重要,否則我傾向於使用std :: stringstream從其組件中構建字符串,然后使用c_str()生成字符串。 這是安全的,因為這樣實際上幾乎沒有緩沖區溢出的機會,而且通常足夠快。

如果分析器告訴我建立字符串是一個熱點,那么您將不得不為了速度而犧牲一些安全性,並開始使用sprintf之類的東西,但我寧願避免這種情況。 總的來說,我會將其作為最后的選擇。

這聽起來確實像是Herb Sutter出色的文章The Manor Farm的String Formatters的案例。

作為記錄:我自己使用std::ostringstream ,構建字符串並傳遞oss.str().c_str()

緩沖區太短導致的一次崩潰將抵消您從sprintf獲得的所有速度節省。 我不認為它反而會更快。 即使是這樣,差異是否也足以令人擔憂?

由於內存管理更加簡便,因此我幾乎總是使用stringstringstream sprintf和其他老式C庫調用很容易出錯。

sprintf樣式函數相對於stringstream的一個好處是,可以輕松地在運行時使用不同格式的字符串,以實現國際化。 但是,您絕對應該使用snprintf或它的其他“更安全”的變體之一。

關於C ++和優雅,我傾向於遵循兩個規則:

  1. 說你的意思。
  2. 首先進行分析,然后進行優化。

您在這里談論的是連接字符串,因此這是我想到的代碼:

std::string s = s1 + s2 + s3 + s4;
foo(s.c_str());

為了“說出您的意思”,我聯系operator + 使用std::stringstream (字符串流)也很不錯,但是我不會立即去使用另一個#include來連接字符串。 我猜這是個人喜好問題。 我絕對不考慮手動構建原始char數組。

就性能而言,我猜測operator +可能是將字符串放在一起的最慢的方法。 但是即使是慢速的方法也可能足夠快達到您的目的。

每天早晨醒來時重復三遍,每晚睡覺前重復三遍:

“過早的優化是萬惡之源。” -努斯

換句話說,請遵循安全,慣用的C ++方式。 當(如果有)速度成為問題時,應該固定速度,而不是以前,尤其是如果在速度之前固定速度會使您的代碼更容易出錯,則應該固定速度。

至於您的第二個問題:查找繩索

您沒有提到平台,但是如果您使用glibc作為標准庫,則可以使用GNU擴展asprintf() ,該擴展會自動分配足夠大的字符串。

有關詳細信息,請參見man asprintf

更通用的方法-首先對未使用的流調用fprintf()只是為了獲取返回的長度,然后分配該字符串並打印到該字符串,如下所示:

FILE *stream = tmpfile();
char *string;

string = malloc(fprintf(stream, format, param)+1);
sprintf(string, format, param);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM