C/C++ 函式庫的運用

sstream - 讀取一行不知道有多少個的數字

sstream 當中的 istringstream 物件,可以以近似於 cin 的方式來讀取一個 string 變數內含的資料。

sstream 的意義為 string stream ,也就是說,把 string 變數看待成 stream 。至於 istringstream 的 i ,應該就是指 input 之意吧。

下面的程式可以讀入一行不知道個數為多少個的數字,並輸出這些數字的總和。

#include <sstream>
#include <iostream>
using namespace std;

int main()
{
    string line;
    while ( getline( cin, line ) )  // 利用 getline() 讀入一行輸入
    {
        // 針對此行建立一個 istringstream 物件    
        istringstream in( line );

        int sum = 0, x;
        while ( in >> x ) sum += x;
        cout << sum << endl;
    }
    return 0;
}

sstream - 讀取不知道有多少行的輸入、並且做 tokenize

int main()
{
    int a, b, c;
    char line[100];

    while (cin.getline(line, 100) && *line)
    {
        istringstream sin(line);
        sin >> a >> b >> c;
        cout << "read abc: " << a << " " << b << " " << c << endl;
    }
    return 0;
}

cstdio - 數字轉字串,字串轉數字

C 的標準函式庫提供了兩個非常好用的函式,可以快速的轉換字串成為數值。

char s[10];
int n;
sscanf(s, "%d", &n);                  // 字串s轉數字n
int length = sprintf(s, "%d", n);     // 數字n轉字串s

cassert - 檢查程式有沒有問題

cassert 當中的 assert() 可以用來檢查程式中的變數數值正不正確。

在程式執行的期間,一旦執行至 assert() 的地方,若是 assert() 括號之中的敘述句不成立,就會跳出程式有問題的視窗。若沒有跳出任何程式有問題的視窗,就意味著程式成功的通過了所有 assert() 的檢查。

下面的這段程式碼利用了 assert() ,藉以檢查 queue 的運算是否如預期所料。

#include <cassert>
#include <queue>
using namespace std;

int main()
{
    queue<int> Q;
    Q.push(8); Q.push(7); Q.push(6); Q.push(2);

    assert(Q.size() == 4);
    assert(Q.back() == 2);

    assert(Q.front() == 8); Q.pop();
    assert(Q.front() == 7); Q.pop();
    assert(Q.front() == 6); Q.pop();
    assert(Q.front() == 2); Q.pop();

    assert(Q.empty());

    return 0;
}

typeinfo - 印出變數型態的名稱

利用 typeid( 變數 ).name 這個語法,可以得到該變數的變數型態。如果該變數是一個物件,則會得到該物件所屬的 class 名稱。範例程式碼如下所示:

#include <typeinfo>
#include <iostream>
using namespace std;

class haha
{
    ......
};

haha obj;
int value = 0;

int main()
{
    cout << typeid(obj).name() << endl;
    cout << typeid(value).name() << endl;

    return 0;
}

此程式執行的結果如下:

class haha
int
iostream - 八、十、十六進位數的輸出入

int num;
cin >> hex >> num;  cout << hex << num; // 讀入/輸出八進位數字
cin >> dec >> num;  cout << dec << num; // 讀入/輸出十進位數字
cin >> oct >> num;  cout << oct << num; // 讀入/輸出十六進位數字

// 讀入/輸出 n 進位數字,但是 n 只能是 8、10、16
#include <iomanip>
cout << setbase(n) << num;  cin >> setbase(n) >> num;

就算使用者輸入 ABC 或 abc (十六進位表示法), compiler 還是可以將之轉換成十進位數字,存到 num 裡面。

十六進位時,輸入的數字有 0x 或 0X 開頭也可以(不要把 0 打成英文字母 o 或 O 了)。

附帶一提,因為 iomanip 已經建好了 hex oct dec 等關鍵字,所以用 setiosflags(ios::hex) 是沒有任何效果的。【有待商榷】

double num;
cin >> num;

就算使用者輸入 2e3 (科學記號表示法), compiler 還是可以將之轉換成十進位數字,存到 num 裡面。

string cstring - 字串運算

一、讀字串,直到遇見空白、換行為止。

string s1, s2;
cin >> s1 >> s2;

char s1[100], s2[100];
cin >> s1 >> s2;

二、讀字串,直到一定數量,或者遇見空白、換行為止。

string s1;
cin >> setw(50) >> s1;

char s1[100];
cin>> setw(50) >> s1;   // 讀入49個字和補一個'\0' 

三、讀一行。

string s1;
getline(cin, s1);   // 要多按一次enter

char s1[100];
cin.getline(s1, 100);

四、讀到特定字元為止。

string s1;
getline(cin, s1, '$');

char s1[100];
cin.getline(s1, 100, '$');

五、交換。

string s1, s2;
s1.swap(s2);

char s1[100], s2[100], temp[100];
strcpy(temp, s1); strcpy(s1, s2); strcpy(s2, temp);

六、長度。

string s1;
int length = s1.length();

char s1[100];
int length = strlen(s1);

七、比大小。

string s1, s2;
if (s1 > s2) parapara...
if (s1 < s2) parapara...
if (s1 == s2) parapara...

char s1[100], s2[100];
if (strcmp(s1,s2) == 1) parapara...
if (strcmp(s1,s2) == -1) parapara...
if (strcmp(s1,s2) == 0) parapara...

等於 -1 時是 a < b : abc 和 edf 、 abc 和 abcde 、 abc 和 acb。
等於 0 時是 a = b : abcde 和 abcde。
等於 1 時是 a > b : b 和 a。

a > b 的意思,就是 a 的字典順序在 b 之後,順序比較大之意。
八、字串後面接字串。

string s1, s2;
s1 += s2;

char s1, s2;
strcat(s1, s2);

ctime - 計時

clock_t start, end;
start = clock();

function(); // 估計function的執行時間

end = clock();
cout << end - start << endl;    // 單位是千分之一秒

ctime - 亂數

#include <iostream>
#include <ctime>
using namespace std;

int main()
{
    // 要先設定一個 random seed,用系統時間來設定
    srand( static_cast< unsigned int >( time(0) ) );

    // 取 0~99 之間的亂數
    for (int i=0; i<10; i++)
    {
        int k = rand() % 100;
        cout << k << "\n";
    }
    return 0;
}

algorithm - 排序

sort() 為 Quick Sort , stable_sort() 為 Merge Sort 。

排序基本資料型態的方法。

int main()
{
    int A[] = {1, 4, 2, 8, 5, 7};
    int N = sizeof(A) / sizeof(int);
    sort(A, A + N);

    vector<int> B(A, A + N);
    sort(B.begin(), B.end());
}

排序自訂資料型態的方法有兩種寫法。

struct Point {int x, y;} A[10];

bool compare(const Point& i, const Point& j)
{
    return i.x < j.x || i.x == j.x && i.y < j.y;
}

int main()
{
    sort(A, A + 10, compare);
}

struct Point
{
    int x, y;

    bool operator<(const Edge& j) const
    {
        return x < j.x || x == j.x && y < j.y;
    }

} A[10];

int main()
{
    sort(A, A + 10);
}
climits - 變數的極值

CHAR_BIT char變數的記憶體大小(bits) 8
MB_LEN_MAX 一個字元的記憶體大小(byte) 1(英文系統) 2(中文系統)
SCHAR_MIN 有號char變數的下限值 -128
SCHAR_MAX 有號char變數的上限值 127
UCHAR_MAX 無號char變數的上限值 255
CHAR_MIN char變數的下限值 -128 或 0
CHAR_MAX char變數的上限值 127 或 255
SHRT_MIN short int變數的下限值 -32768
SHRT_MAX short int變數的上限值 32767
USHRT_MAX 無號short int變數的上限值 65535
INT_MIN int變數的下限 -2147483648
INT_MAX int變數的上限值 2147483647
UINT_MAX 無號int變數的上限值 4294967295
LONG_MIN long int變數的上限值 -2147483648
LONG_MAX long int變數的下限值 2147483647
ULONG_MAX 無號long int變數的下限值 4294967295
附帶一提 < limits.h > 和 < climits > 是屬於 C 的函式庫, C++ 另有推出 < limits > 。

VC++ 和 gcc 同時能使用 long long 的方法

/* Declares 64-bit unsigned integer type 'uint64' */
#ifdef _MSC_VER
typedef unsigned __int64 uint64;
#else
typedef unsigned long long uint64;
#endif
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章