(37)必须会最常用的字符与字符串!`‘\0‘` 详解?getchar函数的使用?putchar函数的使用?gets() 和 puts() 函数的使用?所有输入输出函数总结《小鹅说 C 语言》

部分项目展示

【双人迷宫游戏】:

在这里插入图片描述

【俄罗斯方块】:

在这里插入图片描述

【完整笔记链接】:

https://mp.weixin.qq.com/s/J5bTlJdA613DB9cCb94eag


1、字符

所谓字符就是我们在键盘上敲出来的单个符号,如: A, a, 1, @, #, $, ~ 等等,C 语⾔规定,字符必须要放在单引号中。

前面 (17)常量 - 转义字符 - ASCII 码 章节说过数据类型 char,专门⽤来创建字符变量,而字符变量是⽤来存储字符的。这些字符要想存储起来,就得放在字符变量中,比如:

char ch = 'a'; 

2、字符串

C 语⾔中有字符类型,但是没有字符串类型,字符串就是由双引号引起来的⼀串字符,比如:"abcdef";

⼀个字符串中我们直观的能看到⼀些字符,比如:字符串常量 “abcdef” 中,我们看到了 a、b、c、d、e、f 这 6 个字符,但是实际上在末尾还隐藏⼀个 '\0'转义字符(参考 前面 (17)常量 - 转义字符 - ASCII 码 章节**)**作为字符串结束标志

**注意:**字符串常量的实际字符数总是比其双引号中的字符数多 1,编码过程中的易错点。

3、'\0' 详解

字符串是一系列连续的字符的组合,要想在内存中定位一个字符串,除了要知道它的开头,还要知道它的结尾。

找到字符串的开头很容易,知道它的名字(字符数组名或者字符串名)就可以;

然而,如何找到字符串的结尾呢?

  • 在 C 语言中,字符串总是以'\0'作为结尾,所以'\0'也被称为字符串结束标志

'\0'是 ASCII 码表中的第 0 个字符,英文称为 NULL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在 C 语言中唯一的作用就是作为字符串结束标志

  • " "包围的字符串会自动在末尾添加'\0'

例如,"abc123"从表面看起来只包含了 6 个字符,其实不然,C 语言会在最后隐式地添加一个'\0',这个过程是在后台默默地进行的,所以我们感受不到。

比如以下图示:

双引号括起来的字符串: "hello, world""A"""

在这里插入图片描述

  • C 语言在处理字符串时,从前往后逐个扫描字符,一旦遇到 '\0' 就认为到达了字符串的末尾,就结束处理。

因此:

'\0'至关重要,没有'\0'就意味着永远也到达不了字符串的结尾。

4、单个字符

输入单个字符可以使用 scanf() 这个通用的输入函数,对应的格式控制符为%c,之前 (19)输入 & 输出语句(1) 章节已经讲到了。

4.1、int getchar(void)

函数从屏幕读取下一个可用的字符,并返回为一个整数。它的原型定义在头文件 stdio.h 。

  • 程序运行到这个命令就会暂停,等待⽤户从键盘输⼊。
  • 注意这个函数在同一个时间内只会读取一个单一的字符,等同于使⽤ scanf() 方法读取⼀个字符。
  • getchar() 不会忽略起⾸的空白字符,总是返回当前读取的第⼀个字符,⽆论是否为空格
  • 如果读取失败,返回常量 EOF,由于 EOF 通常是 -1 ,所以返回值的类型要设为 int,而不是 char。

它就是scanf("%c", c)的替代品,除了更加简洁,没有其它优势了;或者说,getchar() 就是 scanf() 的一个简化版本。

4.2、int putchar(int c)

函数把字符输出到屏幕上,并返回相同的字符。它的原型定义在头文件 stdio.h 。

  • putchar() 函数将它的参数字符输出到屏幕。
  • 这个函数在同一个时间内只会输出一个单一的字符,等同于使⽤ printf() 输出⼀个字符。
  • 操作成功时, putchar() 返回输出的字符,否则返回常量 EOF。

可以在循环内使用这个方法,以便在屏幕上输入和输出多个字符。

举例代码如下:

#include <stdio.h>
 
int main( )
{
   int c;
 
   printf( "Enter a value :");
   c = getchar( );
 
   printf( "\nYou entered: ");
   putchar(c);
   printf( "\n");
   return 0;
}

当上面的代码被编译和执行时,它会等待您输入一些文本,当您输入一个文本并按下回车键时,程序会继续并只会读取一个单一的字符,显示如下:

Enter a value :runoob

You entered: r

一句话总结:

接受单个字符和打印单个字符的时候,可以使⽤ getchar 和 putchar。

思维导图:

在这里插入图片描述

4.3、getche() 和 getch()
4.3.1、getche()

它没有缓冲区,输入一个字符后会立即读取,不用等待用户按下回车键,这是它和 scanf()、getchar() 的最大区别

请看下面的代码:

#include <stdio.h>
#include <conio.h>
int main()
{
    char c = getche();
    printf("c: %c\n", c);

    return 0;
}

输入示例:

@c: @

输入@后,getche() 立即读取完毕,接着继续执行 printf() 将字符输出,所以没有按下回车键程序就运行结束了。

4.3.2、getch()

getch() 也没有缓冲区,输入一个字符后会立即读取,不用按下回车键,这一点和 getche() 相同。getch() 的特别之处是它没有回显,看不到输入的字符

所谓回显,就是在控制台上显示出用户输入的字符;没有回显,就不会显示用户输入的字符,就好像根本没有输入一样。

回显在大部分情况下是有必要的,它能够与用户及时交互,让用户清楚地看到自己输入的内容。但在某些特殊情况下,我们却不希望有回显,例如输入密码,有回显是非常危险的,容易被偷窥。

getch() 使用举例:

#include <stdio.h>
#include <conio.h>
int main()
{
    char c = getch();
    printf("c: %c\n", c);

    return 0;
}

输入@后,getch() 会立即读取完毕,接着继续执行 printf() 将字符输出。但是由于 getch() 没有回显,看不到输入的@字符,所以控制台上最终显示的内容为c: @

5、gets() & puts() 函数

我们知道使⽤ scanf 函数,配合 "%s" 的输⼊格式,可以输⼊字符串,使⽤ printf 函数,配合 "%s" 的输出格式,可以输出字符串

现在我们再学习⼀组函数:gets 和 puts。

char *gets(char *s) 函数从标准输⼊ stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。

int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到标准输出 stdout

举例:

#include <stdio.h>
 
int main( )
{
   char str[100];
 
   printf( "Enter a value :");
   gets(str);
 
   printf( "\nYou entered: ");
   puts(str);
   return 0;
}

当上面的代码被编译和执行时,它会等待您输入一些文本,当您输入一个文本并按下回车键时,程序会继续并读取一整行直到该行结束,显示如下:

Enter a value :runoob

You entered: runoob
5.1、详细分析 gets:
#include <stdio.h>
int main()
{
    char arr[10] = {0};
    gets(arr);
    printf("%s\n", arr);
    return 0;
}

存储如图分析所示:

在这里插入图片描述

5.2、puts 与 printf 的区别:
#include <stdio.h>
int main()
{
    char arr1[] = "abc";
    char arr2[] = "def";
    
    printf("%s", arr1);
    printf("%s", arr2);
    printf("\n"); //区分两次打印的效果
    
    puts(arr1);
    puts(arr2);
    
    return 0;
}

我们从结果可以看出,使⽤ printf 函数打印字符串的时候,不会额外加上换行效果,但是 puts 在打印完字符串内容后主动换行。

在这里插入图片描述

5.3、使用 gets() 会报警告:
warning: this program uses gets(), which is unsafe.

gets() 不安全是因为未指定缓冲区大小。可以使用 fgets();

char* fgets(char *buf, int bufsize, FILE *stream);
  • buf:字符型指针,指向用来存储所得数据的地址。
  • bufsize:整形数据,指明缓冲区的大小,拷贝到 buf 地址的最大字符数量。
  • stream:指明输入流的 FILE 对象的指针,stdin 可以作为参数,表示从标准输入读取。

返回值:成功,则函数返回 buf。

如果当尝试读取一个字符时遇到了文件结尾,则 eof 被置位(feof),如果还没有成功读入任何一个字符就遇到了文件结尾,那么就会返回 null,buff 中的内容保持不变。如果读取错误发生,那么 error indicator(ferror) 被置位,还是返回 null。

5.4、输出长文本【拓展】

当文本超出编辑窗口的宽度时,可以选择将文本换行,也可以选择将文本隐藏(可以在编辑器里面自行设置),但是不管哪种形式,在一个字符串里书写长文本不太美观。

#include <stdio.h>
int main()
{
    puts("在 puts 函数中,可以将一个较长的字符串分割成几个较短的字符串,这样会使得长文本的格式更加整齐。");

    return 0;
}

可以多写几个 puts 函数,如下:

#include <stdio.h>
int main()
{
    puts("在 puts 函数中,");
    puts("可以将一个较长的字符串分割成几个较短的字符串");
    puts("这样会使得长文本的格式更加整齐。");

    return 0;
}

在 puts 函数中,可以将一个较长的字符串分割成几个较短的字符串,这样会使得长文本的格式更加整齐。 注意:这只是形式上的分割,编译器在编译阶段会将它们合并为一个字符串,它们放在一块连续的内存中。 多个字符串并不一定非得换行,也可以将它们写在一行中,如下:

#include <stdio.h>
int main()
{
    // 写在几行
    puts(
        "在 puts 函数中,"
        "可以将一个较长的字符串分割成几个较短的字符串"
        "这样会使得长文本的格式更加整齐。"
    );

    // 写在一行
    puts("在 puts 函数中,""可以将一个较长的字符串分割成几个较短的字符串""这样会使得长文本的格式更加整齐。");
    return 0;
}

6、所有输入输出函数总结

6.1、所有输入输出函数

(1)C 语言有多个函数可以从键盘获得用户输入,它们分别是:

  • scanf():是通用的输入函数,它可以读取多种类型的数据。
  • getchar()、getche()、getch():这三个函数都用于输入单个字符。
  • gets():获取一行数据,并作为字符串处理。

(2)C 语言有多个函数可以从键盘获得用户输出,它们分别是:

  • printf():可以输出多种类型的数据。
  • putchar()、putche()、putch():这三个函数都用于输出单个字符。
  • puts():输出一串数据。
6.2、所有输入函数总结

其中 scanf()、getchar()、gets() 是标准函数,适用于所有平台getche() 和 getch() 不是标准函数,只能用于 Windows

函数缓冲区头文件回显适用平台
scanf()stdio.hWindows、Linux、Mac OS 等所有平台
gets()stdio.hWindows、Linux、Mac OS 等所有平台
getchar()stdio.hWindows、Linux、Mac OS 等所有平台
getche()conio.hWindows
getch()conio.hWindows
  • scanf() 是通用的输入函数,它可以读取多种类型的数据。
  • getchar()、getche() 和 getch() 是专用的字符输入函数,在缓冲区和回显方面与 scanf() 有着不同的特性,是 scanf() 不能替代的。
  • gets() 是专用的字符串输入函数,与 scanf() 相比,gets() 的主要优势是可以读取含有空格的字符串

而且:

scanf() 可以一次性读取多份类型相同或者不同的数据,getchar()、getche()、getch() 和 gets() 每次只能读取一份特定类型的数据,不能一次性读取多份数据。

所有输出函数是类似的。

6.3、现象总结
#include <stdio.h>

int main()
{
    int a,b,c;

    a = getchar();
    b = getche();
    c = getch();
}
  1. 执行到 getchar() 函数时,光标闪动,等待输入字符:输入字符后无变化,需要按回车键, 按回车键后,getchar 读取了这个字符,并将其赋值给变量 a。
  2. 执行到 getche() 函数时,光标闪动,等待输入字符:输入字符后,不需按回车键,在输入后,getche 立即读入并赋值给 b。
  3. 执行到 getch() 函数时,光标闪动,等待输入字符:输入字符,并不能看到你输入的字符,屏幕仍是; 但在输入后瞬间,getch() 函数就读取并赋值给了 c。

每日一更!

公众号、优快云等博客:小鹅编程笔记

日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!

在这里插入图片描述

【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍基于Matlab代码实现的四轴飞行器动力学建模仿真方法。研究构建了考虑非线性特性的飞行器数学模型,涵盖姿态动力学运动学方程,实现了三自由度(滚转、俯仰、偏航)的精确模拟。文中详细阐述了系统建模过程、控制算法设计思路及仿真结果分析,帮助读者深入理解四轴飞行器的飞行动力学特性控制机制;同时,该模拟器可用于算法验证、控制器设计教学实验。; 适合人群:具备一定自动控制理论基础Matlab编程能力的高校学生、科研人员及无人机相关领域的工程技术人员,尤其适合从事飞行器建模、控制算法开发的研究生初级研究人员。; 使用场景及目标:①用于四轴飞行器非线性动力学特性的学习仿真验证;②作为控制器(如PID、LQR、MPC等)设计测试的仿真平台;③支持无人机控制系统教学科研项目开发,提升对姿态控制系统仿真的理解。; 阅读建议:建议读者结合Matlab代码逐模块分析,重点关注动力学方程的推导实现方式,动手运行并调试仿真程序,以加深对飞行器姿态控制过程的理解。同时可扩展为六自由度模型或加入外部干扰以增强仿真真实性。
基于分布式模型预测控制DMPC的多智能体点对点过渡轨迹生成研究(Matlab代码实现)内容概要:本文围绕“基于分布式模型预测控制(DMPC)的多智能体点对点过渡轨迹生成研究”展开,重点介绍如何利用DMPC方法实现多智能体系统在复杂环境下的协同轨迹规划控制。文中结合Matlab代码实现,详细阐述了DMPC的基本原理、数学建模过程以及在多智能体系统中的具体应用,涵盖点对点转移、避障处理、状态约束通信拓扑等关键技术环节。研究强调算法的分布式特性,提升系统的可扩展性鲁棒性,适用于多无人机、无人车编队等场景。同时,文档列举了大量相关科研方向代码资源,展示了DMPC在路径规划、协同控制、电力系统、信号处理等多领域的广泛应用。; 适合人群:具备一定自动化、控制理论或机器人学基础的研究生、科研人员及从事智能系统开发的工程技术人员;熟悉Matlab/Simulink仿真环境,对多智能体协同控制、优化算法有一定兴趣或研究需求的人员。; 使用场景及目标:①用于多智能体系统的轨迹生成协同控制研究,如无人机集群、无人驾驶车队等;②作为DMPC算法学习仿真实践的参考资料,帮助理解分布式优化模型预测控制的结合机制;③支撑科研论文复现、毕业设计或项目开发中的算法验证性能对比。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注DMPC的优化建模、约束处理信息交互机制;按文档结构逐步学习,同时参考文中提及的路径规划、协同控制等相关案例,加深对分布式控制系统的整体理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小鹅编程笔记

你的鼓励将是我最大的动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值