问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C/C++中处理带空格字符串输入的几种常用方法

创作时间:
作者:
@小白创作中心

C/C++中处理带空格字符串输入的几种常用方法

引用
CSDN
1.
https://m.blog.csdn.net/2302_81410974/article/details/145444532

在C/C++编程中,如何正确处理带空格的字符串输入是一个常见的问题。本文将详细介绍几种常用的解决方案,包括gets、fgets、scanf、getchar以及C++中的getline函数,并分析它们的优缺点和适用场景。

使用gets函数(不推荐)

gets函数是C语言中最早的字符串输入函数之一,它会从标准输入读取直到遇到换行符\n为止,读取过程中空格不会被截断。因此,gets能够读取带空格的字符串。然而,由于gets无法限制输入的最大长度,若输入的字符串超过预分配的缓冲区大小,会导致缓冲区溢出,进而引发潜在的安全问题。

示例代码:

#include <stdio.h>
int main() {
    char arr[50] = {0};
    gets(arr);  // 从输入读取字符串
    printf("输入的字符串是:%s\n", arr);  // 输出读取的字符串
    return 0;
}

输入示例:

Hello World

输出示例:

输入的字符串是:Hello World

问题:
gets存在缓冲区溢出风险,因此在C++11标准中已废弃,并且强烈不建议使用。

使用fgets函数(推荐)

为了解决gets函数带来的安全隐患,fgets被引入作为替代方案。fgets不仅能够读取带空格的字符串,还允许指定最大读取字符数,从而有效防止缓冲区溢出。

优点:

  • 安全性高:fgets允许限制最大读取长度,避免了缓冲区溢出。
  • 支持空格:能够读取整个行,包括空格。

缺点:

  • 保留换行符:fgets会读取输入中的换行符,需要额外处理。

示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char arr[50] = {0};
    fgets(arr, sizeof(arr), stdin);  // 从输入读取字符串,最多读取49个字符(留出1个位置给 \0)
    arr[strcspn(arr, "\n")] = 0;  // 去掉换行符
    printf("输入的字符串是:%s\n", arr);  // 输出读取的字符串
    return 0;
}

输入示例:

Hello World

输出示例:

输入的字符串是:Hello World

解析:

  • fgets会读取包括空格在内的所有字符,直到遇到换行符\n或达到最大字符数为止。
  • strcspn函数用于查找并移除换行符,确保字符串末尾是正确的空字符\0

总结:

  • fgets是安全的读取带空格字符串的推荐函数,能够有效防止缓冲区溢出。

使用scanf函数

scanf是C语言中常用的输入函数,但它在读取带空格的字符串时有一定局限。标准的%s格式说明符会将空格作为分隔符,导致它不能读取带空格的字符串。然而,我们可以通过%[^\n]格式说明符,告诉scanf读取直到换行符为止的所有字符,包括空格。

优点:

  • 使用简单,能快速读取带空格的字符串。

缺点:

  • 缓冲区溢出:scanf不会限制输入的最大长度,因此仍然存在缓冲区溢出的风险。
  • 换行符问题:scanf会自动跳过换行符,但换行符不会被读取。

示例代码:

#include <stdio.h>
int main() {
    char arr[50];
    scanf("%[^\n]", arr);  // 读取直到换行符
    printf("输入的字符串是:%s\n", arr);  // 输出读取的字符串
    return 0;
}

输入示例:

Hello World

输出示例:

输入的字符串是:Hello World

解析:

  • %[^\n]指示scanf读取直到换行符为止的所有字符,并且包括空格。

总结:

  • scanf可以用来读取带空格的字符串,但需要小心缓冲区溢出的风险。

使用getchar函数逐个字符读取

如果你想更细粒度地控制输入,可以使用getchar函数逐个字符地读取输入。每次调用getchar会读取一个字符,直到遇到换行符\n或文件结束符EOF。这种方法能精确控制输入,适合需要更细致处理的场景。

优点:

  • 完全控制输入过程,适用于特殊输入场景。

缺点:

  • 代码相对繁琐,逐字符处理需要更多代码。

示例代码:

#include <stdio.h>
int main() {
    char arr[50] = {0};
    int ch = 0;
    int i = 0;
    while ((ch = getchar()) != '\n' && ch != EOF) {  // 直到遇到换行符
        arr[i++] = ch;  // 将字符存储到数组中
    }
    arr[i] = '\0';  // 手动加上字符串结束符
    printf("输入的字符串是:%s\n", arr);  // 输出读取的字符串
    return 0;
}

输入示例:

Hello World

输出示例:

输入的字符串是:Hello World

总结:

  • getchar提供了最大控制权,但需要额外处理字符和换行符,适合需要精细控制输入的场景。

使用C++中的getline函数(推荐)

在C++中,getline是处理带空格字符串的最常用函数。它不仅支持读取带空格的字符串,而且会自动调整缓冲区大小,避免缓冲区溢出的问题。getline能够从输入流读取一整行,包括空格和换行符,且无需指定最大输入长度。

优点:

  • 动态内存管理,自动处理缓冲区大小。
  • 简单易用,能处理带空格的字符串。

缺点:

  • 仅适用于C++,不适用于纯C语言。

示例代码:

#include <iostream>
#include <string>
int main() {
    std::string str;
    std::getline(std::cin, str);  // 从标准输入读取一整行,处理带空格
    std::cout << "输入的字符串是:" << str << std::endl;
    return 0;
}

输入示例:

Hello World

输出示例:

输入的字符串是:Hello World

总结:

  • getline是C++中处理带空格字符串的最佳选择,简单且高效,能自动管理内存。

总结

在C/C++中,处理带空格的字符串输入有几种常见的方法:

  1. gets:不推荐使用,存在缓冲区溢出问题,C++11已废弃。
  2. fgets:推荐使用,安全且能处理带空格的字符串,避免溢出问题。
  3. scanf:可以通过%[^\n]格式读取带空格的字符串,但需要小心缓冲区溢出。
  4. getchar:逐个字符读取,适合需要精细控制输入的场景。
  5. C++中的getline:推荐的方式,能自动管理缓冲区,简洁且高效。

根据不同的需求和场景,选择合适的方法进行带空格字符串的输入处理,确保程序的安全性和可维护性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号