c\c++的输入输出

发布于:2025-05-30 ⋅ 阅读:(13) ⋅ 点赞:(0)

c\c++的输入输出

c语言的输入输出

gets()

按下回车键时,从stdin读取一行。
用法示例:

char str[100];
gets(str);

对空白字符的处理:
1.所有空格、Tab等空白字符均被读取,不忽略。
2.按下回车键时,缓冲区末尾的换行符被丢弃,字符串末尾没有换行符\n,缓冲区也没有残留的换行符\n。
注意,gets()不能指定读取上限,因此容易发生数组边界溢出,造成内存不安全。C11 使用了gets_s()代替gets(),但有时编译器未必支持,因此总体来说不建议使用gets()函数来读取输入。

gets()对应的输出函数是puts()。

fgets()

从指定输入流读取一行,输入可以是stdin,也可以是文件流,使用时需要显式指定。

读取stdin示例:

char s1[1005];
fgets(s1,1004,stdin);//换行符占两个字符
char str[100];
memset(str, 0, sizeof(str));
int i = 1;
while (fgets(str, sizeof(str), stdin) != NULL)
    printf("line%d [len %d]: %s", i++, strlen(str), str);

对空白字符的处理:

1.所有空格、Tab等空白字符均被读取,不忽略。
2.按下回车键时,缓冲区末尾的换行符也被读取,字符串末尾将有一个换行符\n。例如,输入字符串hello,再按下回车,则读到的字符串长度为6。
3.fgets()函数会自动在字符串末尾加上\0结束符。

第 2 个参数n指定了读取的最大长度。函数读到n-1个字符(包括换行符\n)就会停止,并在末尾加上\0结束符。剩余字符将残留在缓冲区。

建议使用fgets()完全替代gets()。fgets()对应的输出函数是fputs()。

fgetc & getc()

从指定输入流读取一个字符,输入可以是stdin,也可以是文件流,使用时需要显式指定。

getchar()

从stdin读取一个字符。getchar()实际上也由fgetc()宏定义而来,只是默认输入流为stdin。

用法示例:

char a;
a = getchar();

getchar()常常用于清理缓冲区开头残留的换行符。当知道缓冲区开头有\n残留时,可以调用getchar()但不赋值给任何变量,即可实现冲刷掉\n的效果。

getchar()对应的输出函数是putchar()。

c++的输入输出

cin

cin是 C++ 的标准输入流对象,即istream类的一个对象实例。cin有自己的缓冲区,但默认情况下是与stdin同步的,因此在 C++ 中可以混用 C++ 和 C 风格的输入输出(在不手动取消同步的情况下)。

cin与stdin一样是行缓冲,即遇到换行符时才会将数据同步到输入缓冲区。

cin的用法非常多,只列举常用的几种。最常用的就是使用>>符号(我认为该符号形象地体现了“流”的特点)。

用法示例:

int a, b;
cin >> a >> b;
char str[20];
cin >> str;

cin对空白字符的处理与scanf一致。即:跳过开头空白字符,遇到空白字符停止读取,且空白字符(包括换行符)残留在缓冲区。

如果不想跳过空白字符,可以使用流控制关键词noskipws(no skip white space),但这只对单个字符有效(类似于scanf中的%c)。

char c;
cin >> noskipws >> c;

注意,cin对象属于命名空间std,如果想使用cin对象,必须在 C++ 文件开头写using namespace std,或者在每次用到的时候写成std::cin。

cin.get()

读取单个或指定长度的字符,包括空白字符。

用法示例:

char a, b;
char str[20];

// 读取一个字符,读取失败时返回0,多余字符残留在缓冲区(包括换行符)
a = cin.get();
// 读取一个字符,读取失败时返回EOF,多余字符残留在缓冲区(包括换行符)
cin.get(b);

// 在遇到指定终止字符(参数3)前,至多读取n-1个(参数2)字符
// 当不指定终止字符时,默认为换行符\n
// 如果输入的字符个数小于等于n-1(不含终止字符),则终止字符不残留在缓冲区
// 如果输入的字符个数多于n-1(不含终止字符),则余下字符将残留在缓冲区
cin.get(str, sizeof(str), '\n');

cin.get()读取单个字符时,类似于 C 中的fgetc(),对空白字符的处理也与其一致。cin.get()读取的字符也可以赋值给整型变量。

cin.get()读取指定长度个字符时,类似于 C 中的fgets(),但在换行符的处理上不同。它们都不会使换行符残留在缓冲区,但fgets()会将缓冲区末尾的换行符\n也写入字符串,而cin.get()会丢弃缓冲区末尾的\n。即:当输入test时,用fgets()读取得到的字符串长度为5,用cin.get()读取得到的字符串长度为4。

cin.getline()

读取指定长度的字符,包括空白字符。

用法示例:

char str[20];
cin.getline(str, sizeof(str));    // 第3个参数也可以指定终止字符

cin.getline()与cin.get()指定读取长度时的用法几乎一样。区别在于,如果输入的字符个数大于指定的最大长度n-1(不含终止符),cin.get()会使余下字符残留在缓冲区,等待下次读取;而cin.getline()会给输入流设为 Fail 状态,在主动恢复之前,无法再进行正常输入。

getline()

getline()并不是标准输入流istream的函数,而是字符串流sstream的函数,只能用于读取数据给string类对象,使用时也需要包含头文件。

如果使用getline()读取标准输入流的数据,需要显式指定输入流。

用法示例:

string str;
getline(cin, str);

getline()会读取所有空白字符,且缓冲区末尾的换行符会被丢弃,不残留也不写到字符串结尾。同时,由于string对象的空间是动态分配的,所以会一次性将缓冲区读完,不存在读不完残留在缓冲区的问题。

需要注意的是,假如缓冲区开头就是换行符(比如可能是上一次cin残留的),则getline()会直接读取到空字符串并结束,不会给键盘输入的机会。所以这种情况下要注意先清除开头的换行符。

总结

在 C 中,建议使用scanf()进行格式化读取,用fgets()读取整行,用fgetc()或getchar()读取单个字符。

在 C++ 中,建议使用cin >>进行格式化读取,而cin.get()、cin.getline、getline(string)有各自的适用情况。

注意fgets()和cin.get()在对换行符的清理方面有所区别。