跳到主要内容

C++ 字符串输入输出

什么是C++字符串的输入输出?

在C++编程中,字符串的输入与输出是最基本且最常用的操作之一。无论是接收用户输入的文本,还是向控制台显示信息,掌握字符串的输入输出技术对于开发任何实用程序都至关重要。

C++提供了多种方式来处理字符串的输入和输出,包括:

  • 使用标准输入输出流(cin/cout)
  • 使用getline()函数读取整行
  • 字符串流的使用
  • 文件输入输出操作

本文将详细介绍这些技术,并通过简单示例帮助你掌握它们的使用方法。

使用cin和cout进行基本字符串输入输出

基本输出(cout)

cout是C++中最基本的输出工具,它是在<iostream>库中定义的标准输出流对象。

cpp
#include <iostream>
#include <string>

int main() {
// 使用string类型变量
std::string greeting = "Hello, C++ programmer!";

// 基本输出
std::cout << greeting << std::endl;

// 连接多个输出
std::cout << "The message is: " << greeting << std::endl;

return 0;
}

输出:

Hello, C++ programmer!
The message is: Hello, C++ programmer!

基本输入(cin)

cin是标准输入流对象,用于从键盘读取数据。

cpp
#include <iostream>
#include <string>

int main() {
std::string name;

std::cout << "请输入您的名字: ";
std::cin >> name;

std::cout << "您好," << name << "!" << std::endl;

return 0;
}

如果用户输入张三,输出会是:

请输入您的名字: 张三
您好,张三!
注意

cin >>操作符遇到空格、制表符或换行符就会停止读取。这意味着如果用户输入"张三 李四",那么name变量只会存储"张三"。

使用getline()函数读取整行输入

当需要读取包含空格的完整行文本时,cin >>就不太适用了。这时,我们可以使用getline()函数:

cpp
#include <iostream>
#include <string>

int main() {
std::string fullName;

std::cout << "请输入您的全名: ";
std::getline(std::cin, fullName);

std::cout << "您好," << fullName << "!" << std::endl;

return 0;
}

如果用户输入张三 李四,输出会是:

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

cin和getline()混合使用的陷阱

当在同一程序中混合使用cin >>getline()时,会出现一个常见问题:cin >>不会消耗输入缓冲区中的换行符,而getline()会将换行符作为终止符,这可能导致getline()读取到空行。

cpp
#include <iostream>
#include <string>

int main() {
int age;
std::string description;

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

std::cout << "请描述一下自己: ";
std::getline(std::cin, description);

std::cout << "年龄: " << age << std::endl;
std::cout << "描述: " << description << std::endl;

return 0;
}

上面的代码有一个问题:当用户输入年龄后按回车,cin只读取了数字,留下了换行符在缓冲区中。随后的getline()会读取这个换行符并立即终止,导致description为空字符串。

解决方案:在cin之后、getline()之前,使用cin.ignore()清除输入缓冲区的换行符:

cpp
std::cout << "请输入您的年龄: ";
std::cin >> age;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清除缓冲区直到换行符

std::cout << "请描述一下自己: ";
std::getline(std::cin, description);
提示

要使用numeric_limits,需要包含<limits>头文件:#include <limits>

字符串流操作

C++提供了字符串流类,允许我们像处理文件那样处理字符串。这在解析和格式化字符串时特别有用。

输出字符串流(ostringstream)

cpp
#include <iostream>
#include <string>
#include <sstream>

int main() {
std::ostringstream oss;

// 向字符串流中写入数据
int age = 25;
std::string name = "张三";
double height = 175.5;

oss << "姓名: " << name << ", 年龄: " << age << ", 身高: " << height << "cm";

// 获取结果字符串
std::string result = oss.str();
std::cout << result << std::endl;

return 0;
}

输出:

姓名: 张三, 年龄: 25, 身高: 175.5cm

输入字符串流(istringstream)

cpp
#include <iostream>
#include <string>
#include <sstream>

int main() {
std::string data = "23 45 67 89";
std::istringstream iss(data);

int num;
int sum = 0;

// 从字符串流中读取数字并求和
while (iss >> num) {
sum += num;
}

std::cout << "数字之和: " << sum << std::endl;

return 0;
}

输出:

数字之和: 224

字符串格式控制

使用iomanip库控制输出格式

C++的<iomanip>库提供了多种操纵器(manipulator)来控制输出格式:

cpp
#include <iostream>
#include <iomanip>
#include <string>

int main() {
double price = 123.456;
std::string product = "笔记本电脑";

// 设置浮点数精度
std::cout << "价格: " << std::fixed << std::setprecision(2) << price << std::endl;

// 设置字段宽度和对齐方式
std::cout << "产品名称: " << std::left << std::setw(15) << product << std::endl;
std::cout << "产品编号: " << std::right << std::setw(10) << std::setfill('0') << 12345 << std::endl;

return 0;
}

输出:

价格: 123.46
产品名称: 笔记本电脑
产品编号: 0000012345

文件中的字符串输入输出

C++提供了对文件进行读写操作的能力,这对于处理持久化数据非常有用。

写入字符串到文件

cpp
#include <iostream>
#include <fstream>
#include <string>

int main() {
std::ofstream outFile("example.txt");

if (!outFile.is_open()) {
std::cerr << "无法打开文件!" << std::endl;
return 1;
}

std::string content = "这是一行要写入文件的文本。";
outFile << content << std::endl;
outFile << "这是第二行文本." << std::endl;

outFile.close();
std::cout << "成功写入文件!" << std::endl;

return 0;
}

从文件读取字符串

cpp
#include <iostream>
#include <fstream>
#include <string>

int main() {
std::ifstream inFile("example.txt");

if (!inFile.is_open()) {
std::cerr << "无法打开文件!" << std::endl;
return 1;
}

std::string line;
int lineNumber = 1;

while (std::getline(inFile, line)) {
std::cout << "第 " << lineNumber << " 行: " << line << std::endl;
lineNumber++;
}

inFile.close();
return 0;
}

如果文件内容是我们上面写入的内容,输出会是:

第 1 行: 这是一行要写入文件的文本。
第 2 行: 这是第二行文本.

实际应用案例

案例一:简单文本编辑器

下面是一个简单的文本编辑器,允许用户输入多行文本并保存到文件中:

cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int main() {
std::vector<std::string> lines;
std::string line;

std::cout << "=== 简易文本编辑器 ===" << std::endl;
std::cout << "请输入文本内容 (输入\"保存\"单独一行来结束并保存):" << std::endl;

while (true) {
std::getline(std::cin, line);
if (line == "保存") break;
lines.push_back(line);
}

std::string filename;
std::cout << "请输入文件名: ";
std::getline(std::cin, filename);

std::ofstream outFile(filename);
if (!outFile.is_open()) {
std::cerr << "无法创建文件!" << std::endl;
return 1;
}

for (const auto& textLine : lines) {
outFile << textLine << std::endl;
}

outFile.close();
std::cout << "文件已保存到: " << filename << std::endl;

return 0;
}

案例二:CSV数据解析器

下面是一个简单的CSV解析器,可以从字符串中解析逗号分隔的值:

cpp
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

std::vector<std::string> parseCSV(const std::string& line) {
std::vector<std::string> result;
std::stringstream ss(line);
std::string item;

while (std::getline(ss, item, ',')) {
result.push_back(item);
}

return result;
}

int main() {
std::string csvLine = "张三,23,北京,工程师";

std::vector<std::string> fields = parseCSV(csvLine);

std::cout << "解析结果:" << std::endl;
std::cout << "姓名: " << fields[0] << std::endl;
std::cout << "年龄: " << fields[1] << std::endl;
std::cout << "城市: " << fields[2] << std::endl;
std::cout << "职业: " << fields[3] << std::endl;

return 0;
}

输出:

解析结果:
姓名: 张三
年龄: 23
城市: 北京
职业: 工程师

总结

本文详细讲解了C++中字符串的输入输出操作,包括:

  1. 使用cincout进行基本的字符串输入输出
  2. 使用getline()函数读取整行输入,以及与cin混用时的注意事项
  3. 字符串流的使用,包括istringstreamostringstream
  4. 使用iomanip库控制输出格式
  5. 文件中的字符串输入输出操作

掌握这些技术对于开发几乎所有类型的C++程序都是必不可少的,因为输入输出是程序与用户交互的基础。

练习题

  1. 编写一个程序,从用户那里读取一个包含多个单词的句子,然后统计并输出这个句子中有多少个单词。

  2. 创建一个简单的通讯录程序,允许用户输入联系人的姓名和电话号码,并将这些信息保存到文件中。然后提供一个功能,可以从文件中读取并显示所有联系人。

  3. 编写一个程序,从用户那里读取一个文本文件的名称,然后读取该文件的内容,将所有小写字母转换为大写字母,并将结果写入到一个新文件中。

额外资源