前言:
b站鹏哥视频,来源以下链接
76. 【C语言初阶】操作符_作业讲解_哔哩哔哩_bilibili
目的:
记录视频里面没有理解的相关知识
疑惑的地方:
对c语言的那个,\n不是特别了解,就是输入了一个字符,后面接一个\n,所以对这个具体了解
为啥会输入*号
内容:
题目:BC-48 字母大小写转换
描述
KiKi想完成字母大小写转换,有一个字符,判断它是否为大写字母,如果是,将它转换成小写字母;反之则转换为大写字母。
最先就是说
while (scanf("%c", &ch) == 1)
scanf("%c", &ch)是有返回值的,就是输入一个数,返回为1,错误的数,返回EOF(-1)
真正的问题来了
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char ch = 0;
while (scanf("%c", &ch) == 1)
{
if (ch >='a' && ch <='z')
printf("%c\n", ch - 32);
else
printf("%c\n", ch + 32);
}
return 0;
}
就是说为啥输出上段代码,会显示*,
但是根据评论区的回答,我应该是了解了一点,就是\n+32就是*
但是我的问题是啥呢?
就是说我对讲的不是特别明白,为啥加了一个getchar();就能处理\n
为啥我进去了if循环,我还能进else循环?
为啥会有这个疑问?
因为if,else语句,这两个只能进去一个的,进去了if语句,就不能再进去else语句
解释
我刚刚好像想起来一件事情,就是说
scanf语句,输入一个字母a,他在ch变量中存的实际是这个值, 我之前好像听老师讲缓冲区好像讲过,不知道是不是这个
a\n
然后就进行判断,就先取出ch的变量中的字母a,进行判断,是符合第一个条件,然后输出大写字母a
while (scanf("%c", &ch) == 1)
{
if (ch >='a' && ch <='z')
printf("%c\n", ch - 32);
else
printf("%c\n", ch + 32);
}
这时候if,else语句就结束了,就不会在执行if语句了,他是怎么输出*号的呢?
也就是说,他需要循环第二次,才会执行*号
这时候就得请出我们的ai师傅了,调节几次,终于返回我想要的答案,但是我还是不太理解
一起看看ai师傅的回答
点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cv2pkk4qdqeultlfb70g
简要
关于你的问题:
你提到的“按下换行符,不是会向 ch 变量存储 a\n 吗?”实际上,scanf("%c", &ch) 是逐个读取字符的,不会将 a 和 \n 一起存储到 ch 中。每次循环只读取一个字符,因此:
第一次循环读取 a。
第二次循环读取 \n。
总结:
你的理解是正确的,scanf("%c", &ch) 会逐个读取输入流中的字符,包括换行符。因此,程序的输出确实是:
还是不太理解,鹏哥之前的课程好像详细讲到了缓冲区的问题,我给搞忘求了,这个涉及缓冲区的问题,
while (scanf("%c", &ch) == 1)
问题为啥会只读取一个字符?
ok,根据ai的回答,我差不多理解了,就是说
因为我输入的是%c,这个就是只能从缓冲区读取一个字符,所有的内容都会暂存在缓冲区里的
scanf就是一次只在缓冲区拿一个字符(因为我写的是%c,如果我输入的是%s,他会一次性读取全部的字符)
点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cv2ppmlf8r37f8m6cnng
又有新的问题,如果我从缓冲区拿完全部的字符,那是不是scanf的返回值就是二
而不是1,因为他拿了两个字符,a和\n
测试
实际效果是没有输出这个,哎占卜讨论这个,之前的知识已经解决了
算了还是讨论下吧,都到这里了
解释
%s值提取字符串,但是\n不是一个有效的字符串,然后就返回0,程序就停止
这里值得注意的是%s只会读取\n或空白符之前的字符,也就是说第一次还是只读取了a,第二次读取\n返回0,程序终止
关于%s的用法
下一次循环:
由于换行符
\n
仍然在输入缓冲区中,下一次scanf("%s", &ch)
会读取\n
。由于
\n
不是有效字符,scanf
会返回 0,循环结束。
关于%c的用法
scanf("%c", &ch)
的工作方式
scanf
函数用于从输入流中读取数据。格式化字符串"%c"
表示从输入流中读取一个字符。每次调用scanf("%c", &ch)
时,它会从输入缓冲区中取出下一个字符并存储到变量ch
中。