C++ 字符串输入输出
什么是C++字符串的输入输出?
在C++编程中,字符串的输入与输出是最基本且最常用的操作之一。无论是接收用户输入的文本,还是向控制台显示信息,掌握字符串的输入输出技术对于开发任何实用程序都至关重要。
C++提供了多种方式来处理字符串的输入和输出,包括:
- 使用标准输入输出流(cin/cout)
- 使用getline()函数读取整行
- 字符串流的使用
- 文件输入输出操作
本文将详细介绍这些技术,并通过简单示例帮助你掌握它们的使用方法。
使用cin和cout进行基本字符串输入输出
基本输出(cout)
cout
是C++中最基本的输出工具,它是在<iostream>
库中定义的标准输出流对象。
#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
是标准输入流对象,用于从键盘读取数据。
#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()
函数:
#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()
读取到空行。
#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()
清除输入缓冲区的换行符:
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)
#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)
#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)来控制输出格式:
#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++提供了对文件进行读写操作的能力,这对于处理持久化数据非常有用。
写入字符串到文件
#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;
}
从文件读取字符串
#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 行: 这是第二行文本.
实际应用案例
案例一:简单文本编辑器
下面是一个简单的文本编辑器,允许用户输入多行文本并保存到文件中:
#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解析器,可以从字符串中解析逗号分隔的值:
#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++中字符串的输入输出操作,包括:
- 使用
cin
和cout
进行基本的字符串输入输出 - 使用
getline()
函数读取整行输入,以及与cin
混用时的注意事项 - 字符串流的使用,包括
istringstream
和ostringstream
- 使用
iomanip
库控制输出格式 - 文件中的字符串输入输出操作
掌握这些技术对于开发几乎所有类型的C++程序都是必不可少的,因为输入输出是程序与用户交互的基础。
练习题
-
编写一个程序,从用户那里读取一个包含多个单词的句子,然后统计并输出这个句子中有多少个单词。
-
创建一个简单的通讯录程序,允许用户输入联系人的姓名和电话号码,并将这些信息保存到文件中。然后提供一个功能,可以从文件中读取并显示所有联系人。
-
编写一个程序,从用户那里读取一个文本文件的名称,然后读取该文件的内容,将所有小写字母转换为大写字母,并将结果写入到一个新文件中。