关于字符数组和字符串的输入

1. gets()

1.1 作用与用途:

gets() 是一个从标准输入(stdin)读取字符串的函数,直到遇到换行符或EOF(文件结束符),但不包括换行符。然而,由于 gets() 不检查缓冲区大小,它已经被认为是不安全的,并从C11标准库中移除。

1.2实现原理:

gets() 读取字符,直到遇到换行符或EOF,并将这些字符存储到提供的字符数组中。

1.3 使用场景与示例:

不推荐使用,因为它可能导致缓冲区溢出。

1.4 限制与注意事项:

缓冲区溢出:如果提供的数组不够大,gets() 会覆盖数组后的内存,可能导致程序崩溃或安全问题。

2. getline()

2.1 作用与用途:

在C++中,getline() 是 string 库中的一个函数,用于从输入流(如cin)读取一行,包括空格,直到遇到换行符。

2.2 实现原理:

getline() 读取字符,直到遇到换行符或EOF,并将这些字符(包括空格)存储到 std::string 对象中。

2.3 使用场景与示例:

#include <iostream>  
#include <string>  
using namespace std;
int main() {  
    string line;  
    getline(cin, line);  
    cout << line << endl;  
    return 0;  
}

2.4 限制与注意事项:

如果输入流无效或遇到错误,getline() 可能失败。

3. cin.getline()

3.1 作用与用途:

cin.getline() 是C++ I/O库中的一个成员函数,类似于 getline(),但它是 istream 类的一个方法。

3.2 实现原理:

与 getline() 类似,但它允许指定一个额外的参数来限制读取的字符数。

3.3 使用场景与示例:

#include <iostream>  
using namespace std;
int main() {  
    char line[100];  
    cin.getline(line, 100);  
    cout << line << endl;  
    return 0;  
}

3.4 限制与注意事项:

缓冲区大小限制:必须确保提供的缓冲区足够大,以避免溢出。

4. cin.get()

4.1 作用与用途:

cin.get() 用于从输入流中读取一个字符(包括空格),但不包括换行符。它也可以用于读取一行,但需要额外的逻辑。

4.2 实现原理:

cin.get() 从输入流中读取一个字符,并返回其ASCII值。如果流中没有更多的字符,它将返回EOF。

4.3 使用场景与示例:

#include <iostream>  
using namespace std;
int main() {  
    char ch;  
    ch = cin.get();  
    cout << ch << endl;  
    return 0;  
}

4.4 限制与注意事项:

cin.get() 默认情况下不会跳过空白字符(如空格、制表符或换行符)。如果需要读取整行,可能需要额外的逻辑或使用 getline()。

5. fgets()

5.1 作用与用途:

fgets() 是C语言中的一个函数,用于从指定的流中读取一行,并保存到字符串中。

5.2 实现原理:

fgets() 读取字符,直到遇到换行符、EOF或达到指定的字符数(包括空字符),并将这些字符存储到提供的字符数组中。

5.3 使用场景与示例:

#include <stdio.h>  
  
int main() {  
    char line[100];  
    fgets(line, 100, stdin);  
    printf("%s", line);  
    return 0;  
}

5.4 限制与注意事项:

缓冲区大小限制:与 cin.getline() 类似,必须确保提供的缓冲区足够大。
换行符:fgets() 会将换行符存储在字符串中(如果缓冲区有足够的空间)。如果要去除换行符,需要额外的处理。
安全性:相比 gets(),fgets() 更安全,因为它允许指定缓冲区大小。

关于C++缓冲区的详细讲解:

1. 缓冲区的定义和作用

定义:缓冲区是内存空间的一部分,用于临时存储数据。在C++中,输入/输出流通常与缓冲区相关联,以实现更高效的数据传输。
作用:

  1. 性能优化:缓冲区可以减少与设备(如硬盘或网络)的直接交互次数,从而提高性能。例如,当程序需要从文件读取数据时,它可以从缓冲区中一次性读取多个字节,而不是每次只读取一个字节。
  2. 同步控制:缓冲区允许程序控制何时将数据发送到设备或从设备接收数据。这可以通过刷新(Flushing)缓冲区来实现,即清空缓冲区并将数据发送到目标位置。

2. 缓冲区的类型

  1. 全缓冲:当缓冲区满时,数据才会被发送到目标位置。例如,当文件流与磁盘文件关联时,通常使用全缓冲。
  2. 行缓冲:当在输入或输出中遇到换行符时,缓冲区会被刷新。例如,当与终端(如控制台)交互时,通常使用行缓冲。
  3. 无缓冲:数据直接发送到目标位置,不经过缓冲区。这通常用于错误报告或需要实时反馈的场景。

3. 缓冲区在C++中的实现

C++标准库中的缓冲区:C++标准库中的流类(如std::ifstream, std::ofstream, std::cin, std::cout等)都内置了缓冲区管理。这些类提供了刷新缓冲区的方法(如std::cout::flush())和修改缓冲区行为的方式(如std::ios_base::setbuf())。
自定义缓冲区:在需要更细粒度控制缓冲区行为的情况下,可以定义自定义的缓冲区类。这通常涉及继承std::streambuf类并重写其相关方法。

4. 缓冲区刷新

自动刷新:在某些情况下,C++标准库会自动刷新缓冲区。例如,当程序正常结束时,所有输出缓冲区都会被刷新。
手动刷新:可以使用std::endl操作符或std::flush操纵符来手动刷新缓冲区。例如,std::cout << “Hello, world!” << std::endl;会在输出字符串后刷新输出缓冲区。

5. 缓冲区大小和调整

默认大小:缓冲区的大小通常由C++标准库或操作系统决定,但可以通过自定义缓冲区类来调整。
调整大小:对于自定义缓冲区,可以在创建时指定大小,并在需要时动态调整。然而,对于标准库中的流对象,直接调整其缓冲区大小通常是不可能的。

6. 缓冲区与性能

减少不必要的刷新:频繁地刷新缓冲区会降低性能,因为每次刷新都需要与设备进行交互。因此,在可能的情况下,应尽量减少不必要的刷新操作。
选择适当的缓冲区类型:根据应用场景选择适当的缓冲区类型可以提高性能。例如,对于需要大量读写的文件操作,使用全缓冲可以提高性能;而对于需要与用户进行实时交互的场景,使用行缓冲可能更合适。

输入带空白符的字符数组及字符串的常用方法

1. 使用 std::cin.getline() 读取 char 数组(C风格字符串)

std::cin.getline() 是从标准输入流 std::cin 中读取一行字符串并存储到字符数组中的标准方法。这个方法会读取直到遇到换行符(‘\n’),并将换行符替换为空字符(‘\0’)以标记字符串的结束。

#include <iostream>  
  
int main() {  
    char str[100];  
    std::cout << "Enter a string with spaces: ";  
    std::cin.getline(str, sizeof(str));  
    std::cout << "You entered: " << str << std::endl;  
    return 0;  
}

2. 使用 getline() 读取 string

std::getline() 函数也可以用于从输入流中读取一行字符串到 std::string 对象中。这个方法同样会读取直到遇到换行符。

#include <iostream>  
#include <string>  
  
int main() {  
    std::string str;  
    std::cout << "Enter a string with spaces: ";  
    std::getline(std::cin, str);  
    std::cout << "You entered: " << str << std::endl;  
    return 0;  
}

3. 循环输入(包含数值的循环输入)

// 字符数组
#include <iostream>

using namespace std;
const int maxn = 110;
int main(){
	char arr[maxn];
	while (cin >> arr){
		cout << arr << endl;
	}
	return 0;
}
// 最后输入 ctrl + z并换行,结束输入
// 字符串
#include <iostream>

using namespace std;

int main(){
	string a;
	while (cin >> a){
		cout << a << endl;
	}
	return 0;
}
// 最后输入 ctrl + z并换行,结束输入
// 关于数值输入
#include <iostream>

using namespace std;

int main(){
	int a;
	while (cin >> a){
		cout << a << endl;
	}
	return 0;
}
/*
结束方法:
1. 最后输入 ctrl + z 并换行, 结束输入
2. 最后输入 ctrl + d 并换行,结束输入
3. 最后输入 EOF 并换行,结束输入
*/

3. 总结

对于读取包含空白符的字符串,推荐使用 std::cin.getline()(对于C风格的字符串)或 std::getline()(对于 std::string)。这些方法可以确保读取整个行,包括其中的空白符。而 std::cin 的其他成员函数(如 >>)则更适合于读取不包含空白符的字符串。

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青岛少儿编程-王老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值