字符串输入的一些陷阱

本文详细探讨了C语言中字符串的输入方法,包括如何利用scanf和getchar处理各种符号及空格,避免输入缓冲区残留字符的问题,并给出了多个实用代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串的输入是很基础的问题,不过其中的陷阱也不少。最关键的规避陷阱的方法就是心里清楚输入缓冲(stdio)里还有什么?

以下是十分常见的代码之一,其中scanf("%c", &ch);也经常用getchar(&ch);来写,
它们是一样的。它们有一个优秀之处是,所有的符号,甚至EOF都能获取并返回。
    while(ch != '\n')
    {
        scanf("%c", &ch);
        putchar(ch);
    }
如果需要跳过所有的空格符号,就在%c之前加上‘ ’(空格)就好了。
    while(ch != '#')
    {
        scanf(" %c", &ch);//格式里的空格表示可以跳过所有空格符号
        putchar(ch);
    }
其中需要值得注意的有一点,此时再也无法使用'\n'作为结束接收的界定符号,
因为'\n'会被scanf函数跳过,因而无法返回一个ch = '\n'。
在下面的代码里,我将'#'作为接收的结束界定符号,但是,这样还是会有一个问题!

因为文件是按照行存取的,所以scanf函数被设计成遇到回车'\n'才执行完。
因而你在输入一个串之后不免要按回车,例如你输入“I am a dog.#”之后不免要按下回车结束。
正因为如此,当上述代码运行到ch = '#'为真而跳出循环的时候,在输入缓冲里还留着一个'\n'。
下面贴出一个综合性质的例子。
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char ch ;
    printf("------输入以#结尾------\n") ;
    while(ch != '#')
    {
        scanf(" %c", &ch);//格式里的空格表示可以跳过所有空格符号
        putchar(ch);
    }
    fflush(stdin) ;
    printf("\n-----输入以回车结尾-------\n") ;
    while(ch != '\n') //如果注释了fflush,从上面会留下一个回车至此才被处理
    {                 //因此这一段只getchar一次,就退出循环
        ch = getchar();
        putchar(ch);
    }
    printf("-----输入带空格串-------\n") ;

    char str[100] ;
    gets(str);//允许输入带空格串
    puts(str);

    printf("-----输入带空格串(淫技)-------\n") ;
    scanf("%[^\n]",str);//允许输入带空格串
    puts(str);
    if(getchar() == '\n') puts("That is a '\\n' stay here.");
    printf("-----输入串不允许带空格-------\n") ;
    while(1)
    {
        scanf("%s", str);
        puts(str);
    }

    return 0;
}

下面介绍几个输入一行字符串到buffer的方法,其中的优劣都写在注释里了。

#include<stdio.h>
//3个行输入方案
int readLine(char str[], int n)//周立功新书《程序设计与数据结构》的例子
{
    int ch, i = 0;

    while((ch = getchar()) != '\n')//这样的好处是可以把stdin清除
    {
        if(i < n)
        str[i++] = ch;
    }
    str[i] = '\0';
    return 0;
}
int main(int argc, char *argv[])
{
    int ch ;
    char str[5] ;
    readLine(str,5);//行输入的方法1,我觉得最优秀的方法,不用担心输入缓冲还滞留着字符的问题
    puts(str);
    //memset(str,'\0',5);
    fgets(str, 5, stdin);//遇到\n会结束输入,缺点是没能把sedin清除,优点是把末尾补充'\0',还有缺点就是输入长度不足5的串,会把\n也放进buffer。
    puts(str);

    fread(str,5,1,stdin);//装满buf才结束,没能把sedin清除,末尾不补充'\0'
    puts(str);
    while((ch = fgetchar()) != EOF){
    putchar(ch);
    printf(".");
    }
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值