C++ 不定個數引數寫法
有時候需要寫不定個數引數的函式。就像c語言的sprintf函式。
函式申明方法是比較固定的:
return-type functionName( [type t1] …)
比如: void fun(…);
: int printf ( const char * format, … );
: 省略號的位置就是不定個數的引數列表了。
接下來,給出常見的3種寫法:
方法1:知道資料的具體型別時
比如知道資料是int型。
#include<iosteam> int sum(int a, ...){ int *temp = &a, sum=0; ++temp; for (int i = 0; i < a; ++i) sum+=*temp++; return sum; } int main(){ std::cout<<sum(4, 1, 2, 3, 4)<<std::endl; return 0; }
方法2:使用va_start()、va_end()、va_arg()和vsnprintf()
此方法需藉助於c的庫函式,目前比較常用的是以下4個函式:
#include <stdarg.h> int printf(const char *format, ...); //輸出到標準輸出 int fprintf(FILE *stream, const char *format, ...); //輸出到檔案 int sprintf(char *str, const char *format, ...); //輸出到字串str中 int snprintf(char *str, size_t size, const char *format, ...); //按size大小輸出到字串str中,因為長度限制安全些
還有4個不大常用,但實現功能和以上4個一樣,不過是使用了引數列表va_list。
#include <stdarg.h> int vprintf(const char *format, va_list ap); int vfprintf(FILE *stream, const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); int vsnprintf(char *str, size_t size, const char *format, va_list ap);
後4個函式中,va_start()、va_end()、va_arg()就是實現變長的關鍵了。用法如下(以函式為例):
char s[1000];
int log(char *s, int size, const char *fmt, ...) //該自定義函式,與系統提供的snprintf()函式相同。
{
va_list ap;
int n=0,size=1000;
va_start(ap, fmt); //獲得可變引數列表,分析fmt,得出各個引數的型別,也是分析引數中類似”%d%s“的字串
n=vsnprintf (s, size, fmt, ap); //寫入字串s
va_end(ap); //釋放資源,必須與va_start成對呼叫
return n; //返回寫入的字元個數
}
方法3:使用Boost::format
方法2已經比較實用,但畢竟以c的函式為主,處理不當時可能會出現資料溢位,不易查詢錯誤。這時可以考慮Boost::format,這是Boost的一個功能庫,專門格式化字串,如果出錯會丟擲異常。Boost.Format是一個類,它的可擴充套件性還是不錯的,但效率比起sprintf還是要差不少的。
用法如下:
#include <boost/format.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
int main(){
// 使用%序號%的方式給出指示符,後面用%連線對應的資料。
cout<<format("%1%=%2%")%"x"%1.1<<endl;
// 輸出:x=1.1
// 可以延遲使用,順序不必一致,而且可重用
boost::format fmter("%2% %1%");
fmter % 21;
fmter % 20;
cout << fmter << endl;
// 輸出: 20 21
// 可直接轉成字串
string s = fmter.str();
// 可以使用printf指示符
cout<<format("%.2f-%s")%5.1%"abc"<< endl;
// 輸出:5.10-abc
// printf指示符裡使用N$指定使用第幾個引數
cout<<format("%2$.2f-%1$s%") %5.1%"abc"<< endl;
// 輸出:5.10-abc
}
boost.format指定格式的方式為:
形式為:[ N$ ] [ flags ] [ width ] [ . precision ] type-char
- 其中:N$用於指定第N個引數,但這個引數要麼都加,要麼都不加
- flags用於處理格式,比如對齊。
- width指當前給出寬度
- .precision小數點後多少位
- type-char指資料型別(與sprintf相同)
另外,boost.format有一個方便的用法%N%,如文中第一個示例。
boost.format丟擲的異常有bad_format_string、too_few_args、too_many_args、out_of_range等。
相關推薦
C++ 不定個數引數寫法
有時候需要寫不定個數引數的函式。就像c語言的sprintf函式。 函式申明方法是比較固定的: return-type functionName( [type t1] …) 比如: void fun(…); : int printf ( const char *
Java不定型別,不定個數引數方法的寫法
java方法的不定型別與不定個數引數 public void demo(Object … object ){ } 定義多種型別引數用於測試 int age=12; String name=”李
不定引數個數函式寫法
示例1:初始化一個數組: template <class T> void InitArray(T *dstArray, int c, ...) { va_list arg; va_start(arg, c); for (int i = 0;
C ,不定數量引數
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
關於C語言可變引數函式的寫法及其應用
以前一直以為C語言的函式都是精確匹配的,直到看了 C和C指標 才知道還有可變引數的函式。仔細一想,平時最常用的printf ,scanf 不就是可變引數的嗎。 先上程式碼,隨後詳細講解可變引數函式的用法。 #include<stdio.h> #inc
今天學習了關於C++ 中可變引數個數函式的使用!
VA_LIST 是在C語言中解決變參問題的一組巨集 他有這麼幾個成員 1) va_list型變數: #ifdef _M_ALPHA typedef struct { char *a0; /* pointer tofirst homed inte
c++ 不定引數模板, 待續
1.使用不定引數, 實現c++反射, 初步#include <boost/any.hpp> #include <map> #include <iostream> c
C++不定引數的應用
不定引數當年做為C/C++語言一個特長被很多人推崇,但是實際上這種技術並沒有應用很多。除了格式化輸出之外,我實在沒看到多少應用。主要原因是這種技術比較麻煩,副作用也比較多,而一般情況下過載函式也足以替換它。儘管如此,既然大家對它比較感興趣,我就簡單總結一下它的使用和需要注
C++ 不定參數"..."的使用
va_end orm 參數 ons const system cat nbsp namespace #include <iostream> #include <cstdio> #include <cstdarg> #de
Object... 不定個數的參數列表
查詢 多態 多看 mil 繼承 size objects 固定 說明 Object是所有類的基類,這個你可以查詢jdk文檔了解,所有類都繼承自Object。Object ...objects這種參數定義是在不確定方法參數的情況下的一種多態表現形式。即這個方法可以傳遞多個參數
C++函式與引數
傳值引數:(值傳遞) #include<iostream> using namespace std; int func(int x, int y) { return x + y; } int main() { int a, b, sum; cin >> a >
Html.ActionLink多引數寫法
@Html.ActionLink("刪除此檔案","Action","Controller",new {Id=Id ,area="Admin" },new {@class = "btn btn-danger btn-sm" }) //生成結果: <a class="btn btn-dan
C++ exe傳引數只顯示第一個字元解決方案--C++學習
vs2010新建的工程預設是UNICODE格式的; 你寫程式碼的時候按照UNICODE的格式編碼應該就不會出現上面的問題的。 或者你把工程設定成Use Multi-Byte Character Set,方法如下: Project/工程 -> Properties在彈出對話方塊中選擇
Java中不定項引數(可變引數)的作用和使用方式
引言: 我們在編寫方法的過程中,可能會遇見一個方法有不確定引數個數的情況。一般我們會用方法過載來解決問題: //方法過載,解決引數個數不確定問題 public void method(); public void method(int i); public void method(int
c++ 物件作為引數,指標作為引數,引用作為引數
c++ 引數傳遞方式有三種,分別為:傳物件,傳引用和傳指標,那這三種傳遞方式之間到底有什麼區別呢? 傳物件:是將實參物件的值傳遞給形參物件,是單項傳遞,在函式中修改形參的值時,不會影響到原來實參的值 傳引用:把實參物件名傳給形參物件名,形參物件名就成為實參物件名的別名,實參和形參
c#指定的引數已超出有效值的範圍,引數名:site
除錯專案出現下述問題: 查了一下出現這樣的問題可能是IIS沒有啟動,啟動步驟如下(win10): 1.開啟“控制面板”→“程式”→“啟用或關閉Windows功能”,參考圖:
C++ 命令列引數解析
文章目錄 說明 短引數之 getopt() 長引數之 getopt_long() 長引數之 getopt_long_only() 說明 主要參考以下部落格: 部落格一:getopt和g
關於不定長引數*args的思考
不定長引數*args在函式傳參時十分有用,他能接收任意個引數,當把星號去掉時,相當於把它接收引數’打包‘,當加上星號時,相當於解包: def func(*args): print(*args) print(args) func(1,2,3,4,5)
c#中可變引數(params關鍵字的使用)
一、params 是C#開發語言中關鍵字, params主要的用處是在給函式傳引數的時候用,就是當函式的引數不固定的時候。 在方法宣告中的 params 關鍵字之後不允許任何其他引數,並且在方法宣告中只允許一個 params 關鍵字。 關於引數陣列,需掌握以下幾點。 1、若形參表中含一個引數陣列
C# 可選引數與命名實參
Demo using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Option