文章目录
Linux-C P4 输入输出
基础输入输出
基本输入输出会讲到经常会用到的一些输入输出函数,下面先来介绍关于字符的输入与输出(有关字符等数据类型的内容 参见Linux-C P2 数据类型)
字符输入(getchar)
内容 | |
---|---|
函数名称 | getchar |
所需头文件 | #include <stdio.h> |
函数原型 | int getchar(void) |
函数功能 | 在键盘上读取一个字符 |
函数传入值 | 无 |
函数返回值 | 成功:返回读到的字符 |
失败:-1 |
字符输入函数(getchar),根据函数表可以看出需要调用头文件#include <stdio.h>(有关头文件的介绍,参见 扩展 stdio.h头文件)
它的功能是在键盘上读取一个字符,对是一个字符,你输多了它是不会接收的。
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
char c;
c = getchar();
printf("c = %c\n",c);
return 0;
}
垃圾字符处理
什么是垃圾字符处理呢?
在输入函数输入内容时,你不想要获取却获取到的字符就是垃圾字符
关于scanf函数接收内容时的垃圾字符处理问题
举个栗子
这里输入了数字之后,并没有接着输入字符就直接输出结果了,所以b就是接收了回车,这是因为切换到下一个输入的函数之前我们按了回车,而这个回车就是垃圾字符,因此需要被处理掉。
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a;
char b;
scanf("%d",&a);
getchar();
scanf("%c",&b);
printf("a = %d,b = %c",a,b);
return 0;
}
这里加了一个getchar之后就处理了这个回车,这样我们的程序就能按照想要的样子运行了
字符输出(putchar)
内容 | |
---|---|
函数名称 | putchar |
所需头文件 | #include <stdio.h> |
函数原型 | int putchar(int char) |
函数功能 | 把参数char里的字符打印出来 |
函数传入值 | char:输入的字符(以其对应的int值进行传递) |
函数返回值 | 成功:字符对应的int值 |
失败:-1 |
介绍完字符输入(getchar),接着就是字符输出(putchar),这里可以将需要被打印在终端的字符打印出来
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
int c;
c = getchar();
putchar(c);
return 0;
}
通过getchar获取一个字符内容给c,在通过putchar将c打印出来
是不是很简单呢?
所以来点更有趣的,也是最常用的格式化输入(scanf)和格式化输出(printf)
格式化输入(scanf)
内容 | |
---|---|
函数名称 | scanf |
所需头文件 | #include <stdio.h> |
函数原型 | int scanf(char * format,…) |
函数功能 | 从标准输入方式读取格式化输入 |
函数传入值 | format:[=%[*][width][modifiers]type=] 字符串 |
函数返回值 | 成功:成功匹配和赋值的个数 |
失败:-1 |
格式化输入函数(scanf),重点当然是格式化了,可以通过它读入指定格式的内容
先来介绍一下format传入值应该如何填写吧!
[=%[*][width][length]type=]
参数 | 描述 |
---|---|
* | 可选,表示数据是从流 stream 中读取的,但是可以被忽视,即它不存储在对应的参数中 |
width | 可选,这指定了在当前读取操作中读取的最大字符数 |
length | 可选,用于限定不同说明符的长度,就是说明符的修饰符 |
type | 即说明符的类型 |
这里的*先不做讲解,width和length都是可选的,所以先讲讲这个type后面再来扩展width和length
类型 | 功能 | 参数的类型 |
---|---|---|
%c | 读取下一字符 | char |
%s | 读入字符串 | char |
%d | 读取十进制整数 | int |
%o | 读入八机制整数 | int |
%x、%X | 读入十六进制整数 | int |
%u | 读入无符号的十进制整数 | unsigned int |
%i | 读入十进制、八进制、十六进制整数 | int |
%f | 读取一个单、双精度浮点数(需要使用 lf) | float、double |
%e | 读取指数形式的浮点型 | float、double |
%p | 读入一个指针 |
这里先介绍scanf使用方法,详细例子会在讲完printf之后一起给出。
scanf读取一个字符,注意这里要加上**&**(&的有关内容,可以参见 Liunx-C P7 指针)
char c;
scanf("%c",&c);
scanf读取字符串
char s[100];
scanf("%s",s);
scanf读取十进制整数
int a;
scanf("%d",&a);
scanf读取八进制整数
int b;
scanf("%o",&b);
scanf读取十六进制整数
int c;
scanf("%x",&c);
scanf读取无符号的十进制整数
int d;
scanf("%u",&d);
scanf读取十进制、八进制、十六进制整数
int e;
scanf("%i",&e);
scanf读取一个浮点型
float a;
scanf("%f",&a);
scanf读取一个指数形式浮点型
float b;
scanf("%e",&b);
scanf读取一个指针(这里不做讲解,可以参见 Liunx-C P7 指针)
到了扩展的时候,先来介绍这个width吧
scanf读取指定了长度的内容
float a;
scanf("%5f",&a);
接着再来看看length
修饰符 | 功能 |
---|---|
h | 用于d、o、x前,指定输入为short型整数 |
l | 用于d、o、x前,指定输入为long型整数 |
l | 用于e、f前,指定输入为double型实数 |
scanf读取short型整数
short int a;
scanf("%hd",&a);
scanf读取long型整数
long int b;
scanf("%ld",&b);
scanf读取double型实数
double c;
scanf("%lf",&c);
格式化输出(printf)
内容 | |
---|---|
函数名称 | printf |
所需头文件 | #include <stdio.h> |
函数原型 | int printf(char *format,…) |
函数功能 | 发送格式化输出到标准书stdout |
函数传入值 | format:%[flags][width][.precision][length]specifier |
函数返回值 | 成功:写入的字符总数 |
错误:-1 |
同样的printf的format需要详细的介绍一下,再结合之前的scanf给出例子供大家理解
%[flags][width][.precision][length]specifier
参数 | 描述 |
---|---|
flags | 可选,标志位 |
width | 指定最小字段的宽度 |
.precision | 指定的宽度的精度 |
length | 说明符的长度修饰符 |
specifier | 转换字符(说明符) |
先来看看转换字符*(specifier),功能与scanf里的基本相同
类型 | 功能 | 参数的类型 |
---|---|---|
%c | 读取下一字符 | char |
%s | 读入字符串 | char |
%d | 读取十进制整数 | int |
%o | 读入八机制整数 | int |
%x、%X | 读入十六进制整数 | int |
%u | 读入无符号的十进制整数 | unsigned int |
%i | 读入十进制、八进制、十六进制整数 | int |
%f | 读取一个单、双精度浮点数(需要使用 lf) | float、double |
%e | 读取指数形式的浮点型 | float、double |
%p | 读入一个指针 |
printf读取一个字符
char c = 'c';
printf("c = %c\n",c);
printf读取字符串
char s[100] = "sssss";
printf("s = %s\n",s);
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
char c;
char s[100];
scanf("%c",&c);
scanf("%s",s);
printf("c = %c\n",c);
printf("s = %s\n",s);
return 0;
}
printf读取十进制整数
int a = 12;
printf("%d\n",a);
printf读取八进制整数
int b = 34;
scanf("%o",&b);
printf读取十六进制整数
int c = 56;
printf("%x\n",c);
printf读取无符号的十进制整数
int d = 78;
printf("%u\n",d);
printf读取十进制、八进制、十六进制整数
int e = 90;
printf("%i\n",e);
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a,b,c,d,e;
scanf("%d",&a);
scanf("%o",&b);
scanf("%x",&c);
scanf("%u",&d);
scanf("%i",&e);
printf("%d\n",a);
printf("%o\n",b);
printf("%x\n",c);
printf("%u\n",d);
printf("%i\n",e);
return 0;
}
printf读取一个浮点型
float a = 12.34;
printf("%f\n",a);
printf读取一个指数形式浮点型
float b = 56e7;
printf("%e\n",b);
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
float a,b;
scanf("%f",&a);
scanf("%e",&b);
printf("%f\n",a);
printf("%e\n",b);
return 0;
}
width和.precision
width指定最小字段的宽度,而**.precision则指定了宽度的精度**,就这样说也没有什么深刻的印象
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
float a;
scanf("%5f",&a);
printf("%5.3f\n",a);
return 0;
}
flags是个可选项,加上之后就规定了输入内容的一些标志规定
标志 | 内容 |
---|---|
- | 指定被转换的参数在其字段内容左对齐(默认是右对齐) |
+ | 指定在输出的数前面加上正负号 |
空格 | 如果第一个字符不是正负号,则在其前面加上一个空格 |
0 | 对于数值转换,当输出长度小于字段宽度时,添加前导0进行填充 |
# | 指定另一种输出形式 |
左对齐与右对齐
#include <stdio.h>
int main(int argc, const char *argv[])
{
float a = 12.34;
printf("%10f\n",a);
printf("%-10f\n",a);
return 0;
}
正负号问题
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a = 5,b = -5;
printf("%+d,%+d\n",a,b);
printf("% d\n",a);
return 0;
}
length的功能与scanf的基本相同
修饰符 | 功能 |
---|---|
h | 用于d、o、x前,指定输入为short型整数 |
l | 用于d、o、x前,指定输入为long型整数 |
l | 用于e、f前,指定输入为double型实数 |
printf读取short型整数
short int a;
printf("%hd\n",a);
printf读取long型整数
long int b;
printf("%ld\n",b);
printf读取double型实数
double c;
printf("%lf\n",c);
举个栗子
#include <stdio.h>
int main(int argc, const char *argv[])
{
short int a;
long int b;
double c;
scanf("%hd",&a);
scanf("%ld",&b);
scanf("%lf",&c);
printf("%hd\n",a);
printf("%ld\n",b);
printf("%lf\n",c);
return 0;
}
字符串输入(gets)
内容 | |
---|---|
函数名称 | gets |
所需头文件 | #include <stdio.h> |
函数原型 | char *gets(char *str) |
函数功能 | 从标准输入stdin读取一行,并把它存储在str所指向的字符串中 |
函数传入值 | str:这是指向一个字符数组的指针,该数组存储了c字符串 |
函数返回值 | 成功:返回str |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
char s[100];
printf("input:");
gets(s);
printf("%s\n",s);
return 0;
}
字符串输出(puts)
内容 | |
---|---|
函数名称 | puts |
所需头文件 | #include <stdio.h> |
函数原型 | int puts(const char *str) |
函数功能 | 把一个字符串写入到标准输出stdout |
函数传入值 | str:这是要被写入的c字符串 |
函数返回值 | 成功:返回一个非负值 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
char s[100];
printf("input:");
gets(s);
puts(s);
return 0;
}
文件输入输出
读取文件中一个字符(getc、fgetc)
内容 | |
---|---|
函数名称 | getc |
所需头文件 | #include <stdio.h> |
函数原型 | int getc(FILE *stream) |
函数功能 | 在指定的流stream获取下一个字符,并把位置标识符往前移动 |
函数传入值 | stream:这是指向FILE对象的指针,该FILE对象标识了要在上面执行操作的流 |
函数返回值 | 成功:返回读取的字符 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
char c;
printf("请输入字符:");
c = getc(stdin);
printf("输入的字符:");
putc(c,stdout);
printf("\n");
return 0;
}
内容 | |
---|---|
函数名称 | fgetc |
所需头文件 | #include <stdio.h> |
函数原型 | int fgetc(FILE *stream) |
函数功能 | 从指定的流stream获取下一个字符,并把位置标识符往前移动 |
函数传入值 | stream:这是指向FILE对象的指针,该FILE对象标识了要在上面执行操作的流 |
函数返回值 | 成功:以无符号char强制转换为int的形式返回读取的字符 |
失败:-1 |
编写file.txt
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
int c;
int n = 0;
fp = fopen("file.txt","r");
if(fp == NULL){
perror("打开文件时发生错误");
return -1;
}
do{
c = fgetc(fp);
if(feof(fp)){
break;
}
printf("%c",c);
}while(1);
fclose(fp);
return 0;
}
写入文件中一个字符(putc、fputc)
内容 | |
---|---|
函数名称 | putc |
所需头文件 | #include <stdio.h> |
函数原型 | int putc(int char,FILE *stream) |
函数功能 | 把参数char指定的字符写入到指定的流stream中并把位置标识符往前移动 |
函数传入值 | char:这是要被写入的字符。该字符以其对应的int值进行传递 |
stream:这是指向FILE对象的指针,该FILE对象标识了要被写入字符的流 | |
函数返回值 | 成功:以无符号char强制转换为int的形式返回写入的字符 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
int ch;
fp = fopen("file.txt","w");
for(ch = 65;ch <= 70;ch++){
putc(ch,fp);
}
fclose(fp);
return 0;
}
内容 | |
---|---|
函数名称 | fputc |
所需头文件 | #include <stdio.h> |
函数原型 | int fputc(int char,FILE *stream) |
函数功能 | 把参数char指定的字符写入到指定的流stream中,并把位置标识符往前移动 |
函数传入值 | char:这是要被写入的字符 |
stream:这是指向FILE对象的指针,该FILE对象标识了要被写入的字符流 | |
函数返回值 | 成功:返回被写入的字符 |
失败:-1 |
使用方法与上面的相同
格式化读取文件数据(fscanf)
内容 | |
---|---|
函数名称 | fscanf |
所需头文件 | #include <stdio.h> |
函数原型 | int fscanf(FILE *stream,const char *format,…) |
函数功能 | 从流stream读取格式化输入 |
函数传入值 | stream:这是指向FILE对象的指针,该FILE对象标识了流 |
format:[=%[*][width][modifiers]type=] | |
函数返回值 | 成功:返回成功匹配和赋值的个数 |
失败:-1 |
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
char str1[10],str2[10];
FILE *fp;
fp = fopen("file.txt","w+");
fputs("Hello Cage",fp);
rewind(fp);
fscanf(fp,"%s %s",str1,str2);
printf("Read String1 %s\n",str1);
printf("Read String2 %s\n",str2);
fclose(fp);
return 0;
}
格式化写入文件数据(fprintf)
内容 | |
---|---|
函数名称 | fprintf |
所需头文件 | #include <stdio.h> |
函数原型 | int fprintf(FILE *stream,const char *format,…) |
函数功能 | 发送格式化输出到流stream中 |
函数传入值 | stream:这是指向FILE对象的指针,该FILE对象标识了流 |
format:%[flags][width][.precision][length]specifier | |
函数返回值 | 成功:返回写入的字符总数 |
失败:-1 |
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
FILE *fp;
fp = fopen("file.txt","w+");
fprintf(fp,"%s %s %d","Hello","Cage",2020);
fclose(fp);
return 0;
}
读取文件字符串(fgets)
内容 | |
---|---|
函数名称 | fgets |
所需头文件 | #include <stdio.h> |
函数原型 | char *fgets(char *str,int n,FILE *stream) |
函数功能 | 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。 |
函数传入值 | str :这是指向一个字符数组的指针,该数组存储了要读取的字符串 |
n :这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度 | |
stream :这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流 | |
函数返回值 | 成功:返回相同的 str 参数 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
char str[60];
fp = fopen("file.txt","r");
if(fp == NULL){
perror("打开文件时发生错误");
return -1;
}
if(fgets(str,60,fp)!=NULL){
puts(str);
}
fclose(fp);
return 0;
}
写入文件字符串(fputs)
内容 | |
---|---|
函数名称 | fputs |
所需头文件 | #include <stdio.h> |
函数原型 | int fputs(const char *str,FILE *stream) |
函数功能 | 把字符串写入到指定的流 stream 中,但不包括空字符 |
函数传入值 | str: 这是一个数组,包含了要写入的以空字符终止的字符序列 |
stream: 这是指向FILE对象的指针,改FILE对象标识了要被写入字符串的流 | |
函数返回值 | 成功:非负值 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
fp = fopen("file.txt","w+");
fputs("Hello Cage !!",fp);
fclose(fp);
return 0;
}
读取文件数据(fread)
内容 | |
---|---|
函数名称 | fread |
所需头文件 | #include <stdio.h> |
函数原型 | size_t fread(void *ptr,size_t size,size_t nmemb,FILE *stream) |
函数功能 | 从给定流 stream 读取数据到 ptr 所指向的数组中 |
函数传入值 | ptr: 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针 |
size:这是要读取的每个元素的大小,以字节为单位 | |
nmemb:这是元素的个数,每个元素的大小为 size 字节 | |
stream:这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流 | |
函数返回值 | 成功:读取的元素总数会以 size_t 对象返回 |
失败:-1 |
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE *fp;
char c[] = "Hello Cage";
char buffer[20];
fp = fopen("file.txt","w+");
fwrite(c,strlen(c)+1,1,fp);
fseek(fp,0,SEEK_SET);
fread(buffer,strlen(c)+1,1,fp);
printf("%s\n",buffer);
fclose(fp);
return 0;
}
写入文件数据(fwrite)
内容 | |
---|---|
函数名称 | fwrite |
所需头文件 | #include <stdio.h> |
函数原型 | size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream) |
函数功能 | 把 ptr 所指向的数组中的数据写入到给定流 stream 中 |
函数传入值 | ptr:这是指向要被写入的元素数组的指针 |
size:这是要被写入的每个元素的大小,以字节为单位 | |
nmemb:这是元素的个数,每个元素的大小为 size 字节 | |
stream: 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流 | |
函数返回值 | 成功:读取的元素总数会以 size_t 对象返回 |
失败:-1 |
使用方法同上
数据到字符串
写入格式化数据到字符串(sprintf)
内容 | |
---|---|
函数名称 | sprintf |
所需头文件 | #include <stdio.h> |
函数原型 | int sprintf(char *str,const char *format,…) |
函数功能 | 发送格式化输出到str所指向的字符串 |
函数传入值 | str:指向一个字符数组的指针,该数组存错了C字符串 |
format:这是字符串,包含了要被写入到字符串 str 的文本 | |
函数返回值 | 成功:返回写入的字符总数 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
char s[100];
float f = 1024.1234;
sprintf(s,"s = %f",f);
puts(s);
return 0;
}
写入指定尺寸的格式化数据到字符串(snprintf)
内容 | |
---|---|
函数名称 | snprintf |
所需头文件 | #include <stdio.h> |
函数原型 | int snprintf(char *str,size_t size,const char *format,…) |
函数功能 | 设将可变参数(…)按照 format 格式化成字符串,并将字符串复制到 str 中,size 为要写入的字符的最大数目,超过 size 会被截断 |
函数传入值 | str: 目标字符串 |
size: 拷贝字节数 | |
format:格式化成的字符串 | |
…: 可变参数 | |
函数返回值 | 成功:指定最大范围内的字符串长度 |
失败:-1 |
#include <stdio.h>
int main(int argc, const char *argv[])
{
char s[100];
float f = 1024.1234;
snprintf(s,16,"s = %f ffsesegseg",f);
puts(s);
return 0;
}