2010-05-12 66 views
10

我有一個8位的整數,我想打印格式化這樣的整數:格式化在C++

XXX-XX-XXX

我想用一個函數,它的int,並返回一個字符串。

這樣做的好方法是什麼?

回答

11

這就是我個人的做法。可能不是解決問題的最快方式,絕對不像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, "-"); 
}; 
+0

絕對最容易理解(即讀)的所有答案。 – Inverse 2010-05-12 05:46:35

1
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; 

http://www.ideone.com/17eRv

它不是一個功能,但其用於通過數字解析一個int數的一般方法。

3

您可以使用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 
} 
1

這是怎麼回事?

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的問題。我知道,這很醜。

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; 
} 
+1

爲什麼malloc的,我們在C++這裏 – 2010-05-12 02:23:25

+1

爲什麼手工分配?如果有的話,使緩衝區自動,而不是動態('sizeof(char)'總是1,因爲它是一個很好的數字,使緩衝區爲16),'sprintf',然後返回一個'std :: string'。 – GManNickG 2010-05-12 02:29:20

6

測試這一點,它的工作原理。

這裏的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; 
} 
+0

+1以獲得更一般的解決方案。 – andand 2010-05-12 02:49:58

+1

+ 0違反YAGNI :-) – paxdiablo 2010-05-12 02:57:25

+3

但是'cout << foo(「### - ##」,12345)<< endl'是做什麼用的?如果該函數只能處理一個特定長度的格式字符串,則應該聲明這一點。國際海事組織你應該'斷言'範圍條件而不是默默地失敗。 – msandiford 2010-05-12 03:16:33

4

這裏有一個完整的程序,說明如何我做到這一點:

#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 

最後兩個顯示了測試的重要性。如果你想要不同的行爲,你需要修改代碼。如果呼叫者不能被打擾(或者太愚蠢)來跟隨他們,我通常會選擇無聲執行規則,但顯然有些人喜歡使用最少驚訝和提出異常的原則:-)

1
#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; 
} 
+0

只要格式字符串的X個字符的數量等於整數的長度,該算法就可以使用任何整數。例如,對於8位數的整數,格式字符串必須包含8個X字符。 – wilhelmtell 2010-05-12 03:13:44

+0

因此,根據'first == last'而不是'n == 0'終止可能會更好。 – 2012-12-26 15:41:33

5

下面是嘗試與標準庫工作,並得到它做了大部分工作的有點不同的方式:

#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()

這可能是矯枉過正,如果你只是想打印出一個數字,這樣,但是如果你想要做這樣的事情在多個地方(或,特別是,如果你想格式化所有數字去以這種方式到特定的流),它變得更合理。

+3

我真的無法真正看到太多人以這種方式解決這個特定的問題,但最真實的答案是+1。 – msandiford 2010-05-12 12:54:32

-1

您不需要mallocnew,只是定義bufchar buff[11];