格式化在C++
回答
這就是我個人的做法。可能不是解決問題的最快方式,絕對不像egrunin的功能那樣可重用,但它讓我覺得既乾淨又容易理解。我會把它放在環中作爲一種替代更大和更環的解決方案。
#include <sstream>
#include <string>
#include <iomanip>
std::string format(long num) {
std::ostringstream oss;
oss << std::setfill('0') << std::setw(8) << num;
return oss.str().insert(3, "-").insert(6, "-");
};
int your_number = 12345678;
std::cout << (your_number/10000000) % 10 << (your_number/1000000) % 10 << (your_number/100000) %10 << "-" << (your_number/10000) %10 << (your_number/1000) %10 << "-" << (your_number/100) %10 << (your_number/10) %10 << (your_number) %10;
它不是一個功能,但其用於通過數字解析一個int數的一般方法。
您可以使用std :: ostringstream類將數字轉換爲字符串。然後,您可以使用數字串並使用任何格式打印它們,如下面的代碼所示:
std::ostringstream oss;
oss << std::setfill('0') << std::setw(8) << number;
std::string str = oss.str();
if (str.length() != 8){
// some form of handling
}else{
// print digits formatted as desired
}
這是怎麼回事?
std::string format(int x)
{
std::stringstream ss
ss.fill('0');
ss.width(3);
ss << (x/10000);
ss.width(1);
ss << "-";
ss.width(2);
ss << (x/1000) % 100;
ss.width(1);
ss << "-";
ss.width(3);
ss << x % 1000;
return ss.str();
}
編輯1:我看到strstream已被廢棄,用字符串流所取代。
編輯2:修復了丟失前導0的問題。我知道,這很醜。
顯然是char *
而不是string
,但你明白了。你需要釋放輸出一旦你完成,並且很可能需要添加錯誤檢查,但是這應該這樣做:
char * formatter(int i)
{
char *buf = malloc(11*sizeof(char));
sprintf(buf, "%03d-%02d-%03d", i/100000, (i/1000)%100, i%1000);
return buf;
}
爲什麼malloc的,我們在C++這裏 – 2010-05-12 02:23:25
爲什麼手工分配?如果有的話,使緩衝區自動,而不是動態('sizeof(char)'總是1,因爲它是一個很好的數字,使緩衝區爲16),'sprintf',然後返回一個'std :: string'。 – GManNickG 2010-05-12 02:29:20
測試這一點,它的工作原理。
這裏的format
參數是「XXX-XX-XXX」,但它只查看(和跳過)破折號。
std::string foo(char *format, long num)
{
std::string s(format);
if (num < 0) { return "Input must be positive"; }
for (int nPos = s.length() - 1; nPos >= 0; --nPos)
{
if (s.at(nPos) == '-') continue;
s.at(nPos) = '0' + (num % 10);
num = num/10;
}
if (num > 0) { return "Input too large for format string"; }
return s;
}
用法:
int main()
{
printf(foo("###-##-###", 12345678).c_str());
return 0;
}
+1以獲得更一般的解決方案。 – andand 2010-05-12 02:49:58
+ 0違反YAGNI :-) – paxdiablo 2010-05-12 02:57:25
但是'cout << foo(「### - ##」,12345)<< endl'是做什麼用的?如果該函數只能處理一個特定長度的格式字符串,則應該聲明這一點。國際海事組織你應該'斷言'範圍條件而不是默默地失敗。 – msandiford 2010-05-12 03:16:33
這裏有一個完整的程序,說明如何我做到這一點:
#include <iostream>
#include <iomanip>
#include <sstream>
std::string formatInt (unsigned int i) {
std::stringstream s;
s << std::setfill('0') << std::setw(3) << ((i % 100000000)/100000) << '-'
<< std::setfill('0') << std::setw(2) << ((i % 100000)/1000) << '-'
<< std::setfill('0') << std::setw(3) << (i % 1000);
return s.str();
}
int main (int argc, char *argv[]) {
if (argc > 1)
std::cout << formatInt (atoi (argv[1])) << std::endl;
else
std::cout << "Provide an argument, ya goose!" << std::endl;
return 0;
}
具有一定的投入運行這給:
Input Output
-------- ----------
12345678 123-45-678
0 000-00-000
7012 000-07-012
10101010 101-01-010
123456789 234-56-789
-7 949-67-289
最後兩個顯示了測試的重要性。如果你想要不同的行爲,你需要修改代碼。如果呼叫者不能被打擾(或者太愚蠢)來跟隨他們,我通常會選擇無聲執行規則,但顯然有些人喜歡使用最少驚訝和提出異常的原則:-)
#include <iostream>
#include <string>
using namespace std;
template<class Int, class Bi>
void format(Int n, Bi first, Bi last)
{
if(first == last) return;
while(n != 0) {
Int t(n % 10);
n /= 10;
while(*--last != 'X' && last != first);
*last = t + '0';
}
}
int main(int argc, char* argv[])
{
int i = 23462345;
string s("XXX-XX-XXX");
format(i, s.begin(), s.end());
cout << s << endl;
return 0;
}
只要格式字符串的X個字符的數量等於整數的長度,該算法就可以使用任何整數。例如,對於8位數的整數,格式字符串必須包含8個X字符。 – wilhelmtell 2010-05-12 03:13:44
因此,根據'first == last'而不是'n == 0'終止可能會更好。 – 2012-12-26 15:41:33
下面是嘗試與標準庫工作,並得到它做了大部分工作的有點不同的方式:
#include <locale>
template <class T>
struct formatter : std::numpunct<T> {
protected:
T do_thousands_sep() const { return T('-'); }
std::basic_string<T> do_grouping() const {
return std::basic_string<T>("\3\2\3");
}
};
#ifdef TEST
#include <iostream>
int main() {
std::locale fmt(std::locale::classic(), new formatter<char>);
std::cout.imbue(fmt);
std::cout << 12345678 << std::endl;
return 0;
}
#endif
返回一個字符串,只寫一個字符串流,並返回其.str()
。
這可能是矯枉過正,如果你只是想打印出一個數字,這樣,但是如果你想要做這樣的事情在多個地方(或,特別是,如果你想格式化所有數字去以這種方式到特定的流),它變得更合理。
我真的無法真正看到太多人以這種方式解決這個特定的問題,但最真實的答案是+1。 – msandiford 2010-05-12 12:54:32
您不需要malloc
或new
,只是定義buf
爲char buff[11];
- 1. 在C++中格式化列
- 2. 號在C#格式化
- 3. 在C中格式化SprintF
- 4. 在C格式化日曆
- 5. 格式化C++ setw
- 6. C#列格式化
- 7. C printf格式化
- 8. C#格式化MessageBox
- 9. C#格式化數
- 10. c#格式化CSV
- 11. 在C++中從格式化到非格式化輸入切換
- 12. C++格式化如Visual Studio C#格式化
- 13. C#DateTimeOffset格式化爲特定格式
- 14. 格式化輸出C++
- 15. 格式化C字符串
- 16. C++浮點格式化
- 17. objective-c代碼格式化
- 18. 用C++格式化貨幣
- 19. c和格式化輸出
- 20. 格式化C#輸出
- 21. 格式化Objective-C代碼
- 22. Try-Catch格式化C#
- 23. C#控制檯格式化
- 24. 字符串格式化C#
- 25. 格式化文件 - C++
- 26. sscanf格式化輸入C++
- 27. C#貨幣格式化(「C2」)
- 28. DBF數字格式化C#
- 29. C#+字符串格式化
- 30. C#雙重格式化
絕對最容易理解(即讀)的所有答案。 – Inverse 2010-05-12 05:46:35