1. 程式人生 > >C++ 不定個數引數寫法

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