gets()
函数原型
char *gets(char *str);
说明
gets 从标准输入读取字符,直到遇到换行符(\n)或文件结束(EOF)。换行符不会被存储到 str 中,而是在字符串末尾自动添加一个空字符(\0)作为字符串的结束标志。
参数
str:指向一个字符数组的指针,用于存储读取的字符串。
返回值
成功时,返回指向 str 的指针。
如果遇到文件结束(EOF)或发生错误,返回 NULL。
其他说明
- 支持带空格的字符串输入,如: “a bcd”
- gets()函数最大的问题在于越界,gets()函数已在ISO/IEC 9899:TC3中被弃用并在C11中被删除。
- 永远不要使用gets()!
fgets()
原型
char *fgets(char *str, int n, FILE *stream);
说明
fgets函数用于从指定的输入流中读取一行字符串,并将其存储到指定的字符数组中。与 gets 不同,fgets 会限制读取的字符数,从而避免缓冲区溢出问题
参数
str:指向一个字符数组的指针,用于存储读取的字符串。
n:最大读取字符数(包括结尾的空字符 \0)。
stream:输入流,通常为 stdin(标准输入)或文件指针。
返回值
成功时,返回指向 str 的指针。
如果遇到文件结束(EOF)或发生错误,返回 NULL。
其他说明
- 一般用来替换gets函数
- 换行符(如果存在)会被存储到 str 中,这个容易出错,一般不希望有这个换行符
#include <cstring>
#include <stdio.h>
int main() {
char str[100];
char *p;
printf("请输入一个字符串: ");
if (fgets(str, sizeof(str), stdin) != NULL) {
printf("你输入的字符串是: %s,字符串长度为:%d\n", str,strlen(str));
if (p=strchr(str, '\n'))
{
printf("找到换行符:0x%x, 所在位置:%d", (int)*p, p-str);
}
} else {
printf("读取输入时发生错误。\n");
}
return 0;
}
执行结果如下,包含了结尾的换行符。
请输入一个字符串: a b
你输入的字符串是: a b
,字符串长度为:4
找到换行符:0xa, 所在位置:3
getchar()
原型
int getchar(void);
说明
getchar 函数用于从标准输入(通常是键盘)读取一个字符
返回值
成功时,返回读取的字符(以 int 类型返回)
如果遇到文件结束(EOF)或发生错误,返回 EOF
其他说明
返回值的类型是 int,而不是 char。这是因为 getchar 需要能够返回所有可能的字符值以及一个特殊值 EOF(表示文件结束或错误)
gets_s()
原型
char *gets_s(char *str, rsize_t n);
说明
gets_s 函数是 C11 标准中引入的一个安全版本的字符串输入函数,用于替代不安全的 gets 函数。gets_s 通过限制输入的长度,避免了缓冲区溢出的问题
参数
str:指向一个字符数组的指针,用于存储读取的字符串。
n:缓冲区 str 的大小,表示最多可以读取的字符数(包括结尾的空字符 \0)。
返回值
成功时,返回指向 str 的指针。
如果遇到文件结束(EOF)、输入错误或缓冲区大小无效,返回 NULL。
其他说明
它会读取字符,直到遇到换行符(\n)或文件结束(EOF)。
换行符不会被存储到 str 中,而是在字符串末尾自动添加一个空字符(\0)。
C语言getline()
原型
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
说明
getline 函数是 C 标准库中的一个函数,用于从文件流中读取一行字符串。与 gets 和 fgets 不同,getline 可以动态分配内存来存储输入的字符串,因此非常适合处理不确定长度的输入。该函数是 POSIX 标准的一部分,在 GNU C 库(glibc)中广泛使用。
参数
lineptr:
指向字符指针的指针,用于存储读取的字符串。
如果 *lineptr 为 NULL,getline 会自动分配内存。
如果 *lineptr 不为 NULL,getline 会尝试使用已分配的内存,如果内存不足,则会重新分配。
n:
指向 size_t 类型的指针,表示 *lineptr 指向的缓冲区大小。
getline 会更新 *n 为实际分配的缓冲区大小。
stream:
文件流指针,通常为 stdin(标准输入)或文件指针。
返回值
成功时,返回读取的字符数(包括换行符,但不包括结尾的空字符 \0)。
如果遇到文件结束(EOF)或发生错误,返回 -1。
其他说明
getline 从指定的文件流中读取一行字符串,直到遇到换行符(\n)或文件结束(EOF)。
换行符(如果存在)会被存储到字符串中。
字符串末尾会自动添加一个空字符(\0)。
动态内存分配:
getline 会根据需要动态分配内存,因此不需要预先指定缓冲区大小。
如果 *lineptr 为 NULL,getline 会自动调用 malloc 分配内存。
如果 *lineptr 不为 NULL,但缓冲区大小不足,getline 会调用 realloc 重新分配内存。
内存管理:
由 getline 分配的内存需要手动释放(使用 free)。
POSIX 标准,windows系统可能不支持
示例
#include <stdio.h>
#include <stdlib.h>
int main() {
char *line = NULL; // 初始化为 NULL,getline 会自动分配内存
size_t len = 0; // 初始长度为 0
ssize_t read;
printf("请输入一行字符串: ");
read = getline(&line, &len, stdin); // 从标准输入读取一行
if (read != -1) {
printf("你输入的字符串是: %s", line);
printf("读取的字符数: %zd\n", read);
} else {
printf("读取输入时发生错误。\n");
}
free(line); // 释放动态分配的内存
return 0;
}
输出结果:
请输入一行字符串: a b
你输入的字符串是: a b
读取的字符数: 4
C++: cin
说明
在 C++ 中,cin 是标准输入流对象,用于从用户输入中读取数据。对于字符串的输入,cin 提供了多种方式,具体取决于需求。
cin 可以直接用于输入string类型的字符串,但它会在遇到空白字符(空格、制表符、换行符等)时停止读取。
示例
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
cout << "请输入一个字符串: ";
cin >> str;
cout << "你输入的字符串是: " << str << endl;
return 0;
}
输出:
请输入一个字符串: Hello World
你输入的字符串是: Hello
C++: getline()
原型
标准字符串版本
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
字符数组版本
istream& getline (char* s, streamsize n, char delim);
istream& getline (char* s, streamsize n);
说明
getline 是 C++ 标准库中的一个函数,用于从输入流中读取整行字符串(包括空格),直到遇到换行符或可选的分隔符;分隔符会被从输入流中提取但不会存储到字符串中
参数
is:输入流对象(如 cin 或文件流)
str:存储读取内容的字符串对象
delim:可选的分隔符(默认为换行符 ‘\n’)
示例1
#include <iostream>
#include <string>
int main() {
std::string line;
// 从标准输入读取一行
std::getline(std::cin, line);
// 使用自定义分隔符
std::getline(std::cin, line, ','); // 读取直到遇到逗号
std::cout << "You entered: " << line << std::endl;
return 0;
}
示例2
#include <iostream>
int main() {
char buffer[100];
// 从标准输入读取一行到字符数组
std::cin.getline(buffer, 100);
std::cout << "You entered: " << buffer << std::endl;
return 0;
}
其他说明
getline与 >> 操作符混用:在使用 >> 后使用 getline() 时,可能需要先清除输入缓冲区,因为 >> 会留下换行符。
int num;
std::string line;
std::cin >> num;
std::cin.ignore(); // 忽略剩余的换行符
std::getline(std::cin, line);
**错误处理:**可以通过检查返回值来判断读取是否成功
if (!std::getline(std::cin, line)) {
// 处理错误
}
**文件读取:**常用于逐行读取文件
std::ifstream file("example.txt");
std::string line;
while (std::getline(file, line)) {
// 处理每一行
}
文件重定向到标准输入
原型
FILE *freopen(const char *filename, const char *mode, FILE *stream);
说明
freopen() 是 C 标准库中的一个函数,用于重定向标准输入/输出流到指定文件。在 C++ 中也可以使用,但更推荐使用 C++ 的流重定向机制。
参数
filename:要打开的文件名
mode:文件打开模式(与 fopen() 相同)
stream:要重定向的流(stdin, stdout, stderr)
常用模式
模式 描述
“r” 只读方式打开文本文件
“w” 只写方式创建/清空文本文件
“a” 追加方式打开文本文件
“r+” 读写方式打开文本文件
“w+” 读写方式创建/清空文本文件
“a+” 读写方式追加打开文本文件
“rb”, “wb” 等 二进制模式
返回值
成功时:返回第三个参数 stream 本身(即重定向后的文件流指针)
失败时:返回 NULL,并且会关闭原始流
示例
#include <stdio.h>
int main() {
// 重定向标准输入到 input.txt
freopen("input.txt", "r", stdin);
// 重定向标准输出到 output.txt
freopen("output.txt", "w", stdout);
int a, b;
scanf("%d%d", &a, &b); // 从 input.txt 读取
printf("%d\n", a + b); // 写入 output.txt
// 恢复标准输出到控制台
freopen("/dev/tty", "w", stdout); // Linux
// freopen("CON", "w", stdout); // Windows
printf("结果已写入output.txt\n");
return 0;
}
其他说明
freopen() 不是线程安全的,多线程环境下需谨慎使用
C++中的替代方案:
#include <fstream>
std::ifstream in("input.txt");
std::ofstream out("output.txt");
// 重定向cin和cout
std::cin.rdbuf(in.rdbuf());
std::cout.rdbuf(out.rdbuf());