C++字符串的輸入輸出整理


最近在跟一門北大C++程序設計的慕課,openjudge上做到一道題,要求定義一種能夠輸入輸出學生姓名,年齡,學號和學年成績的類。比較特別的是輸入的形式是以逗號隔開的一長串字符串。

我用的方法通過是通過了,但可能比較笨,主要使用getline獲取指定字符之前的字符串,使用強制轉換函數stoi()轉換成數字。

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <cstdlib>
using namespace std;

class Student {
private:
    string m_name, m_id;
    unsigned m_age;
    double m_av, n[4];

public:
    void input()
    {
        string ts = {};    
        getline(cin, m_name, ',');    //從流中獲取姓名的字符串,遇到逗號結束
        getline(cin, ts, ',');    //從流中獲取年齡的字符串
        m_age = stoi(ts);    //強制轉化為整型賦給成員變量m_age
        getline(cin, m_id, ',');    //從流中獲取學號的字符串,賦給成員變量m_id
        for (int i = 0; i < 3; i++)    //獲取前三個學年的成績,同樣用強制轉換存值
        {
            getline(cin, ts, ',');
            n[i] = stoi(ts);
        }
        getline(cin, ts, '\n');    //獲取最后一個學年的成績,遇到換行符結束
        n[3] = stoi(ts);    
    }
    void calculate()
    {
        m_av = (n[0] + n[1] + n[2] + n[3]) / 4;    //計算四個學年成績的平均值
    }
    void output()
    {
        cout << m_name << "," << m_age << "," << m_id << "," << m_av;
    }
};

int main() {
    Student student;        // 定義類的對象
    student.input();        // 輸入數據
    student.calculate();    // 計算平均成績
    student.output();       // 輸出數據

    system("pause");
    return 0;
}

 


 

這里總結一下我迄今使用的字符串輸入輸出的方式。

 

1.cin

cin會從流中取數據,遇到空格或者換行符都會停止,所以不適合讀數據串。一般用來取單個變量的數據。

int a; int b;
    cin >> a;
    cin >> b;
    cout << "a:" << a << endl;
    cout << "b:" << b << endl;

輸入:

2 3(回車)

 

2(回車)
3(回車)

輸出:

a:2
b:3

第一種輸入會把換行符之前,即“2+空格+3+\n”的數據都存入緩沖區。程序執行到cin>>a,去緩沖區取數據,碰到空格停止,所以就取走了一個2賦給了a,然后繼續執行cin>>b,此時緩沖區如果還殘留數據,程序會從緩沖區取數據而不是要求用戶輸入,所以重復相同的步驟取走了剩余的3。最后,留下一個換行符在緩沖區內

 

2.cin.get()

cin.get()如果不加任何參數的話,只會每次從緩沖區取一個數據,同樣也會留下換行符。要注意的是,cin.get()遇到換行符就會停止,意思是緩沖區如果留有換行符,此時程序執行cin.get()會被直接跳過。cin.get()返回的值可以直接賦給變量。

int a; int b;
    a = cin.get();
    b = cin.get();

    cout << "a:" << a << endl;
    cout << "b:" << b << endl;

輸入:

abc(回車)

輸出:

a:97
b:98

發現cin.get()取的實際是單個字符,如果賦給整型的話就會轉化成對應的ASCII值。

再如:

char a, b;
    cin >> a;
    b = cin.get();

    cout << "a:" << a << endl;
    cout << "b:" << b << endl;

輸入:

1(回車)

輸出:

a:1
b:

剛才說過cin>>a讀取了回車之前的數據給了a,但會緩沖區留下個換行符。然后cin.get()從緩沖區取數據,遇到換行符直接就跳過了,所以沒有提示用戶輸入,b沒有賦值。

如果不把cin.get()的返回值賦給誰,自成一句,那么cin.get()就可以用來清除掉緩沖區的字符

如:

char a[10];

    a[0] = cin.get();
    a[1] = cin.get();
    cin.get();
    cin.get();
    a[2] = cin.get();

    cout << a[0] << a[1] << a[2] << endl;

輸入:

abcde

輸出:

abe

cd被推走了,所以只有abe賦了值。

利用這一特性,常留一句cin.get()清掉緩沖區殘留的換行符,或者無效的輸入。

cin.get()加參數的話,第一項填數據名,第二項填其長度,就可以給特定字符變量輸入字符串了。

如:

char a[10];
cin.get(a,10);

 

3.getline

getline可以給字符串string對象賦值,用法如下:

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

int main()
{
    char str1[10];
    string str2;

    cin.get(str1, 10);
    cin.get();    //清除換行符
    getline(cin,str2);

    cout << "str1:" << str1 << endl;
    cout << "str2:" << str2 << endl;
    
    system("pause");
}

輸入:

abcd(回車)
hijk(回車)

輸出:

str1:abcd
str2:hijk

getline可以指定第三項參數,即遇到特定的字符停止,默認是‘\n’,可以手動寫成如‘,’,也就是我在上面例題程序里使用的。

 

值得注意的是將string轉換成int的函數 stoi() 還是挺有用的,需要包含頭文件<string>。

string str;
    int a ;
    cin >> str;
    a = stoi(str);

    cout << "a:" << a << endl;

輸入:

100(回車)

輸出:

a:100

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM