跳到主要内容

C++ 输入输出

C++中的输入输出操作是与用户交互和处理数据的基础。无论是从键盘读取数据,还是向屏幕输出结果,或者是与文件进行交互,掌握输入输出是编程的第一步。

输入输出流概述

在C++中,输入输出操作通过流(stream)来实现。流是一种抽象,它代表了数据的来源或目的地。C++提供了多种流类型,它们都包含在<iostream>头文件中:

  • cin:标准输入流,通常连接到键盘
  • cout:标准输出流,通常连接到屏幕
  • cerr:标准错误流,用于输出错误信息
  • clog:标准日志流,用于输出日志信息

这些流对象都是预定义的,无需创建即可使用。

标准输出 (cout)

标准输出流 cout 用于向屏幕输出数据。它与 << 运算符(称为插入运算符)一起使用。

cpp
#include <iostream>
using namespace std;

int main() {
cout << "Hello, World!" << endl;

int age = 25;
cout << "I am " << age << " years old." << endl;

double pi = 3.14159;
cout << "The value of pi is approximately " << pi << endl;

return 0;
}

输出:

Hello, World!
I am 25 years old.
The value of pi is approximately 3.14159
提示

endl 用于插入换行符并刷新输出缓冲区。你也可以使用 '\n' 仅插入换行符。

标准输入 (cin)

标准输入流 cin 用于从键盘读取用户输入。它与 >> 运算符(称为提取运算符)一起使用。

cpp
#include <iostream>
using namespace std;

int main() {
int age;
cout << "请输入您的年龄: ";
cin >> age;
cout << "您的年龄是: " << age << " 岁" << endl;

string name;
cout << "请输入您的姓名: ";
cin >> name;
cout << "您好, " << name << "!" << endl;

return 0;
}

假设用户输入:

20
张三

输出:

请输入您的年龄: 20
您的年龄是: 20 岁
请输入您的姓名: 张三
您好, 张三!
警告

使用 cin >> 读取字符串时,它会在遇到空白字符(如空格、制表符、换行符)时停止读取。如果需要读取包含空格的整行文本,应使用 getline() 函数。

读取整行文本 (getline)

要读取包含空格的整行文本,可以使用 getline() 函数:

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

int main() {
string fullName;
cout << "请输入您的全名: ";

// 注意:如果之前使用了cin>>,需要先清除缓冲区
// cin.ignore(numeric_limits<streamsize>::max(), '\n');

getline(cin, fullName);
cout << "您好, " << fullName << "!" << endl;

return 0;
}

假设用户输入:

张三 李四

输出:

请输入您的全名: 张三 李四
您好, 张三 李四!

输入输出的混合使用

在同一程序中混合使用不同的输入方法时,需要特别注意缓冲区问题:

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

int main() {
int age;
string name, description;

cout << "请输入您的年龄: ";
cin >> age;

cout << "请输入您的姓名: ";
// 清除之前输入可能留下的换行符
cin.ignore();
getline(cin, name);

cout << "请简单介绍一下自己: ";
getline(cin, description);

cout << "\n个人信息摘要:" << endl;
cout << "年龄: " << age << endl;
cout << "姓名: " << name << endl;
cout << "介绍: " << description << endl;

return 0;
}

格式化输出

C++提供了多种方法来格式化输出,使其更加美观和易读。要使用这些功能,需要包含 <iomanip> 头文件。

cpp
#include <iostream>
#include <iomanip> // 用于格式控制
using namespace std;

int main() {
// 设置浮点数精度
double pi = 3.14159265358979;
cout << "默认精度的pi: " << pi << endl;
cout << "精确到2位小数的pi: " << fixed << setprecision(2) << pi << endl;

// 设置字段宽度和对齐
cout << "\n数字表格:" << endl;
cout << setw(10) << "数字" << setw(10) << "平方" << setw(10) << "立方" << endl;

for(int i = 1; i <= 5; i++) {
cout << setw(10) << i
<< setw(10) << i*i
<< setw(10) << i*i*i << endl;
}

// 设置填充字符
cout << "\n使用不同的填充字符:" << endl;
cout << setfill('-') << setw(30) << "" << setfill(' ') << endl;

// 设置进制
int num = 255;
cout << "十进制: " << dec << num << endl;
cout << "十六进制: 0x" << hex << uppercase << num << endl;
cout << "八进制: 0" << oct << num << endl;

return 0;
}

输出:

默认精度的pi: 3.14159
精确到2位小数的pi: 3.14

数字表格:
数字 平方 立方
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125

使用不同的填充字符:
------------------------------
十进制: 255
十六进制: 0xFF
八进制: 0377

文件输入输出

除了标准输入输出外,C++还支持文件输入输出操作。这需要包含 <fstream> 头文件。

写入文件

cpp
#include <iostream>
#include <fstream>
using namespace std;

int main() {
// 打开文件进行写入
ofstream outFile("example.txt");

// 检查文件是否成功打开
if (!outFile.is_open()) {
cerr << "无法打开文件进行写入" << endl;
return 1;
}

// 写入数据到文件
outFile << "这是第一行文本。" << endl;
outFile << "这是第二行文本。" << endl;

int num = 42;
double pi = 3.14159;

outFile << "数字: " << num << endl;
outFile << "圆周率: " << pi << endl;

// 关闭文件
outFile.close();

cout << "数据已成功写入文件!" << endl;

return 0;
}

读取文件

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

int main() {
// 打开文件进行读取
ifstream inFile("example.txt");

// 检查文件是否成功打开
if (!inFile.is_open()) {
cerr << "无法打开文件进行读取" << endl;
return 1;
}

string line;
cout << "文件内容:" << endl;

// 逐行读取文件内容
while (getline(inFile, line)) {
cout << line << endl;
}

// 关闭文件
inFile.close();

return 0;
}

字符串流

C++还提供了字符串流,用于在内存中进行输入输出操作,需要包含 <sstream> 头文件。

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

int main() {
// 字符串输出流
ostringstream oss;

// 向字符串流写入数据
int id = 101;
string name = "张三";
double score = 95.5;

oss << "学号: " << id << ", 姓名: " << name << ", 分数: " << score;

// 获取字符串流中的内容
string studentInfo = oss.str();
cout << "学生信息: " << studentInfo << endl;

// 字符串输入流
string data = "123 3.14 Hello";
istringstream iss(data);

// 从字符串流读取数据
int intValue;
double doubleValue;
string stringValue;

iss >> intValue >> doubleValue >> stringValue;

cout << "整数: " << intValue << endl;
cout << "浮点数: " << doubleValue << endl;
cout << "字符串: " << stringValue << endl;

return 0;
}

输出:

学生信息: 学号: 101, 姓名: 张三, 分数: 95.5
整数: 123
浮点数: 3.14
字符串: Hello

实际应用案例:学生成绩管理系统

以下是一个简单的学生成绩管理系统,展示了C++输入输出在实际应用中的使用:

cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;

// 学生结构体
struct Student {
string name;
int id;
vector<double> scores;
double average;
};

// 计算平均分
double calculateAverage(const vector<double>& scores) {
double sum = 0;
for (double score : scores) {
sum += score;
}
return sum / scores.size();
}

// 显示学生信息
void displayStudent(const Student& student) {
cout << setw(10) << student.id
<< setw(15) << student.name
<< setw(10) << fixed << setprecision(2) << student.average;

for (double score : student.scores) {
cout << setw(8) << score;
}
cout << endl;
}

// 显示所有学生
void displayAllStudents(const vector<Student>& students) {
cout << "\n----- 学生成绩表 -----\n" << endl;
cout << setw(10) << "学号" << setw(15) << "姓名" << setw(10) << "平均分";

for (int i = 1; i <= students[0].scores.size(); i++) {
cout << setw(8) << "科目" + to_string(i);
}
cout << endl;

for (int i = 0; i < 50; i++) cout << "-";
cout << endl;

for (const Student& student : students) {
displayStudent(student);
}
}

// 保存学生信息到文件
void saveToFile(const vector<Student>& students, const string& filename) {
ofstream outFile(filename);

if (!outFile.is_open()) {
cerr << "无法打开文件进行写入: " << filename << endl;
return;
}

for (const Student& student : students) {
outFile << student.id << "," << student.name << ",";

for (double score : student.scores) {
outFile << score << ",";
}

outFile << student.average << endl;
}

outFile.close();
cout << "数据已成功保存到文件: " << filename << endl;
}

int main() {
vector<Student> students;
int subjectCount;

cout << "欢迎使用学生成绩管理系统\n" << endl;
cout << "请输入科目数量: ";
cin >> subjectCount;

while (true) {
cout << "\n1. 添加学生\n"
<< "2. 显示所有学生\n"
<< "3. 保存到文件\n"
<< "4. 退出\n"
<< "请选择操作: ";

int choice;
cin >> choice;

if (choice == 1) {
Student student;
student.scores.resize(subjectCount);

cout << "请输入学生学号: ";
cin >> student.id;

cin.ignore(); // 清除缓冲区的换行符
cout << "请输入学生姓名: ";
getline(cin, student.name);

for (int i = 0; i < subjectCount; i++) {
cout << "请输入科目 " << i + 1 << " 的成绩: ";
cin >> student.scores[i];
}

student.average = calculateAverage(student.scores);
students.push_back(student);

cout << "学生信息添加成功!" << endl;
}
else if (choice == 2) {
if (students.empty()) {
cout << "没有学生记录!" << endl;
} else {
displayAllStudents(students);
}
}
else if (choice == 3) {
if (students.empty()) {
cout << "没有学生记录可保存!" << endl;
} else {
string filename;
cout << "请输入文件名: ";
cin >> filename;
saveToFile(students, filename);
}
}
else if (choice == 4) {
cout << "感谢使用学生成绩管理系统,再见!" << endl;
break;
}
else {
cout << "无效的选择,请重新输入!" << endl;
}
}

return 0;
}

总结

C++的输入输出系统通过流的概念提供了灵活且强大的数据传输机制。通过本教程,我们学习了:

  1. 标准输入输出流(cincout)的基本使用
  2. 读取整行文本(getline
  3. 输出格式控制
  4. 文件输入输出操作
  5. 字符串流的使用
  6. 一个实际的应用案例

掌握这些基础知识后,你将能够轻松处理C++中的各种输入输出需求。

小贴士

在实际开发中,良好的输入验证和错误处理是非常重要的。总是检查输入是否有效,文件是否成功打开,以提高程序的健壮性。

练习

  1. 编写一个程序,从用户输入中读取一个整数n,然后读取n个整数存入数组,最后计算并输出它们的平均值。
  2. 编写一个程序,读取一个文本文件,统计其中的字符数、单词数和行数。
  3. 编写一个通讯录程序,允许用户添加、显示和搜索联系人信息,并能将数据保存到文件和从文件中读取。
  4. 修改学生成绩管理系统,添加从文件读取学生信息的功能。

附加资源

掌握输入输出操作对于几乎所有C++程序都是必不可少的,通过持续练习,你会发现这些知识在日常编程中的广泛应用。