C++ peek函數用法詳解

2020-07-16 10:04:42
peek 成員函數與 get 類似,但有一個重要的區別,當 get 函數被呼叫時,它將返回輸入流中可用的下一個字元,並從流中移除該字元;但是,peek 函數返回下一個可用字元的副本,而不從流中移除它。

因此,get() 是從檔案中讀取一個字元,但 peek() 只是"看"了下一個字元而沒有真正讀取它。為了更好地理解這種差異,假設新開啟的檔案包含字串 "abc",則以下語句序列將在螢幕上列印兩個字元 "ab":

char ch = inFile.get () ; // 讀取一個字元
cout << ch;    //輸出字元
ch = inFile.get () ; // 讀取另一個字元
cout << ch; //輸出字元

但是,以下語句則將在螢幕上列印兩個字元 "aa":

char ch = inFile.peek () ; //返回下一個字元但是不讀取它
cout << ch;    //輸出字元
ch = inFile.get () ; //現在讀取下一個字元
cout << ch; //輸出字元

當需要在實際閱讀之前知道要讀取的資料型別時,peek 函數非常有用,因為這樣就可以決定使用最佳的輸入方法。如果資料是數位的,最好用流提取操作符 >> 讀取,但如果資料是非數位字元序列,則應該用 get 或 getline 讀取。

下面的程式使用 peek 函數通過將檔案中出現的每個整數的值遞增 1 來修改檔案的副本:
// This program demonstrates the peek member function.、
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
    // Variables needed to read characters and numbers
    char ch;
    int number;
    // Variables for file handling
    string fileName;
    fstream inFile, outFile;
    // Open the file to be modified
    cout << "Enter a file name: ";
    cin >> fileName;
    inFile.open(fileName.c_str(), ios::in);
    if (!inFile)
    {
        cout << "Cannot open file " << fileName;
        return 0;
    }
    // Open the file to receive the modified copy
    outFile.open("modified.txt", ios::out);
    if (!outFile)
    {
        cout << "Cannot open the outpur file.";
        return 0;
    }
    // Copy the input file one character at a time except numbers in the input file must have 1 added to them
    // Peek at the first character
    ch = inFile.peek();
    while (ch != EOF)
    {
        //Examine current character
        if (isdigit(ch))
        {
            // numbers should be read with >>
            inFile >> number;
            outFile << number + 1;
        }
        else
        {
            // just a simple character, read it and copy it
            ch = inFile.get();
            outFile << ch;
        }
        // Peek at the next character from input file
        ch = inFile.peek();
    }
    // Close the files
    inFile.close();
    outFile.close ();
    return 0;
}

程式測試檔案內容:
Amy is 23 years old. Robert is 50 years old. The difference between their ages is 27 years. Amy was born in 1986.
程式輸出結果:
Amy is 24 years old. Robert is 51 years old. The difference between their ages is 28 years. Amy was born in 1987.

該程式事先無法知道下一個要讀取的字元是一個數位還是一個普通的非數位字元(如果是數位,則應該使用流提取操作符 >> 來讀取整個數位;如果是字元,則應該通過呼叫 get() 成員函數來讀取)。

因此,程式使用 peek() 來檢查字元而不實際讀取它們。如果下一個字元是一個數位,則呼叫流提取操作符來讀取以該字元開頭的數位;否則,通過呼叫 get() 來讀取字元並將其複製到目標檔案中。