1.控制台读入读出
1.2.字符串
(1)相关函数:
读入函数 | gets(), scanf() |
读出函数 | puts(), printf() |
gets(): char *gets(char *s)
- 返回值:读入成功时,返回与参数相同的指针;遇到EOF或错误时,返回NULL(可通过feof或ferror检查时哪种错误)。
- 无输入上限,直到接受到换行符或EOF时停止。
- 换行符不作为读取串的内容,会被转换为'\0'空字符,以此来结束字符串。
- 不安全,容易造成堆栈溢出,可使用fgets()取代。
- 例子如下:
#include <stdio.h>
#include <string.h>
int main()
{
char msg[20];
memset(msg, 0, sizeof(msg));
gets(msg);
printf("msg input: %s\n", msg);
return 0;
}
- 返回值:成功时返回非负数;失败时返回EOF。
- 等同于printf("%s\n", s);因此输出字符串后会自动输出换行符。
- 可使用fputs()取代。
- 例子如下:
#include <stdio.h>
#include <string.h>
int main()
{
char msg[20];
memset(msg, 0, sizeof(msg));
gets(msg);
puts(msg);
return 0;
}
- 返回值:本次成功读入的数据项数;失败时返回EOF。
- 格式化输入多个字符串,格式串中的空白符[空格符,TAB符,换行符]使得scanf()在输入流中跳过一个或多个空白符。
- %[]的用法:要读入的字符集合,如果[后面第一个字符是"^",则表示相反的意思。
- 非即读模式,缓冲区问题:格式错误时立即返回,换行符的'\n'。
- 例子如下:
#include <stdio.h>
int main()
{
int i = 0;
char j = 0;
for(i=0; i<10; i++)
{
scanf("%c",&j);
}
printf("%c", j);
return 0;
}
运行结果截图:
注:当输入<Enter>键后,scanf从缓冲区中依次读入<'a', ' ', 'b', ' ', 'c' , ' ', 'd', ' ', 'e', ' '>,因此输出结果为空格符。以下输入则正确:
#include <stdio.h>
int main()
{
char str_1[20];
char str_2[20];
scanf("%[^,],%[^\n]", str_1, str_2);
printf("%s\n%s\n", str_1, str_2);
return 0;
}
结果截图如下:
注:%[^,]表示遇逗号字符停止,逗号作为分隔符,%[^\n]表示换行符作为该字符串结束符(不过滤空格符等)。
#include <stdio.h>
int main()
{
int a = 0, b = 0, c = 0, ret = 0;
ret = scanf("%d%d%d", &a, &b, &c);
printf("first value: %d\n", ret);
ret = scanf("%d%d%d", &a, &b, &c);
printf("second value: %d\n", ret);
return 0;
}
运行结果截图:
注:按<Enter>键后,第一个scanf()读入<a(1)>,到b的时候,因为格式不正确,错误返回,即正确读入1个数据。而后输出ret=1;
执行到第二个scanf()时,因为缓冲区中依然有数据<''a 3''>,因此继续读取,然格式依然错误,继续返回,即正确读入0个数据。故输出ret=0。
#include <stdio.h>
int main()
{
int i = 0;
char ch = ' ';
while(ch != 'N')
{
scanf("%d", &i);
scanf("%c", &ch);
printf("a=%d,ch=%c\n", i, ch);
}
return 0;
}
运行结果截图:
注:第一次按下<Enter>键后,第一个scanf()读入了3,第二个读入了'\n',因此直接就执行了printf()语句。
第二次输入N,再<Enter>后,第一个scanf()错误返回,因此i的值不改变,N被ch读入,而后直接执行printf()语句。
但如果把ch换成int型的变量,则不会自动读入'\n'符,而是等待输入。
scanf()的特点:"%d%d":会忽略掉输入的空白符,但遇到输入字符型时会直接返回;而"%c%c":不会忽略输入的空白符,会把输入的1看成字符'1',不会直接返回。
printf(): int printf(const char *format, .....)
- 返回值:实际输出的字符个数。
- 非即刻输出字符串:会先输出到缓冲区,待一定条件时才会输出到屏幕,任一条件:
- 使用fflush(stdout)强制刷新。
- 缓冲区已满。
- scanf()要在缓冲区里取数据时会先将缓冲区刷新。
- '\n','\r'进入缓冲区时。
- 线程结束的时候,如果该线程里也有printf()。
- 程序结束时。
- 例子如下:
#include <stdio.h>
#include <unistd.h>
#define MAXSIZE 5
int main()
{
int i = 0;
char str[MAXSIZE];
for(i = 0; i < MAXSIZE; i++)
{
str[i] = 'H';
}
printf("%s",str);
sleep(3);
return 0;
}
字符会在3秒之后输出;在Windows平台上,可以使用#include <windows.h>的Sleep(ms)函数来取代sleep(s)进行测试。