more more的三种用法 1 2 3 more filename //分页显示文件内容 command | more //将command命令的输出分页显示 more < filename //more从标准输入中获取要分页显示的内容,而标准输入被从重定向到filename
enter显示下一行,space显示下一页,q退出
管道命令|将command的输出重定向到more的输入
例如命令ls /bin | more,ls命令的标准输出重定向到more的标准输入,如果还是使用getchar()来读取用户的输入,那么就会从ls的输出中读取,这显然不行,所以需要其他方式
/dev/tty 通过在more命令中打开/dev/tty文件进行读取的方式,使得more可以从其他途径中获取到用户输入
键盘和显示器的设备描述文件
向这个文件写相当于显示在用户的屏幕上,读相当于从键盘获得用户的输入
C函数 gets 1 2 3 #include <stdio.h> char *gets (char *s) ;
将读取到内容保存在s中,遇到换行符、文件结尾时读取结束,不会检查输入会溢出s的大小
该函数于C11已经废弃
返回值:读取正确返回s,发生错误返回NULL,溢出则什么可能都会发生
fgets 1 2 3 4 5 6 7 8 #include <stdio.h> int fgetc (FILE *stream) ;char *fgets (char *s, int size, FILE *stream) ;int getc (FILE *stream) ;int getchar (void ) ;int ungetc (int c, FILE *stream) ;
fgets:读取到size-1个字符(最后一个位置会填上\0),遇到换行符,文件结尾时结束
返回值:
对于fgets如果返回s表示读取成功,如果返回NULL表示读取错误或者什么都没有读取到
对于其他函数(除了ungetc),返回读取到的字符转化为int的值,返回EOF表示错误或者读取到了文件结尾
fputs 1 int fputs (const char *str, FILE *stream) ;
返回值:该函数返回一个非负值,如果发生错误则返回 EOF(-1)。
fgetc 1 int fgetc (FILE *stream) ;
功能是从文件指针指定的文件中读入一个字符,该字符的ASCII值作为函数的返回值。
若返回值为EOF,说明文件结束。如果发生错误也返回 EOF(-1)
perror
使用perror()函数,它可以自己查找错误代码,并在标准错误输出中显示相应的错误信息
参数:string是同时显示的描述信息,例如对于文件操作的代码,可以把文件名作为描述信息传进去
1 2 #include <stdio.h> void perror (const char *s) ;
strtoul 1 2 #include <stdlib.h> unsigned long int strtoul (const char *nptr, char **endptr, int base) ;
该函数尝试将字符串转换为一个无符号长整型
参数:
nptr:待转换的字符串
endptr:如果传入指针不为NULL,则返回nptr中首个不为合法数字的字符的地址(使用指针的指针就是为了能够修改指针的内容);当遇到首个不合法字符时,转换过程停止。
base:应该以何种进制来解释字符串中的数字 ,该值可以传入2~36,或者特殊值0;如果传入0则该函数会根据字符串首部来确定进制:
如果 nptr 以 “0x” 或 “0X” 开头,则基数为 16。
如果 nptr 以 “0” 开头,则基数为 8。
否则,基数为 10。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> #include <stdlib.h> int main () { const char *str = "12345abcd" ; char *end; unsigned long int value; value = strtoul(str, &end, 10 ); printf ("转换结果: %lu\n" , value); printf ("未转换的部分: %s\n" , end); return 0 ; }
输出:
1 2 转换结果: 12345 未转换的部分: abcd
C语言知识复习
声明字符串的两种方式 1 2 char *str = "hello wrold" ;char str[] = "hello wrold" ;
char *str里的str是指针变量,指向一个字符串常量
sizeof(str):返回的是指针变量的大小,而不是字符串的长度
str[0] = 'H:会报Segment fault错误,常量字符串不可修改
str = "Hello":指针可以修改指向不同的常量字符串
char str[]里str是地址常量,str的值是str[]的地址,它声明了一个字符数组
sizeof(str):返回字符串的大小,包括’\0’
C语言的内存分配方式 内存分配可分为三种:静态存储区、栈区、堆区。
1、静态存储区:该内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,它主要存放静态数据、全局数据和常量。 2、栈区:它的用途是完成函数的调用。在执行函数时,函数内局部变量及函数参数的存储单元在栈上创建,函数调用结束时这些存储单元自动被释放。 3、堆区:程序在运行时使用库函数为变量申请内存,在变量使用结束后再调用库函数释放内存。动态内存的生存期是由我们决定的,如果我们不释放内存,就会导致内存泄漏。
linux系统调用 read 1 2 #include <unistd.h> ssize_t read (int fd, void *buf, size_t count) ;
open
1 2 3 #include <fcntl.h> #include <sys/types.h> int open (const char *pathname, int flags, mode_t mode) ;
close 1 2 #include <unistd.h> int close (int fd) ;
ctime 1 2 #include <time.h> char *ctime (const time_t *timep) ;
返回值:格式为"Wed Jun 30 21:49:08 1993\n"的字符串
time_t为long int类型
utmp文件中的ut->time表示用户从登录时间到初始时间所经过的秒数
creat 1 2 #include <fcntl.h> int creat (const char *pathname, mode_t mode) ;
参数:
mode:访问模式,传入三个用户组的权限对于该文件的权限(mode_t应该是unsigned int类型)
返回值:成功返回文件描述符,失败返回-1
没有则创建文件,如果文件存在则它的内容会被清空。
write 1 2 #include <unistd.h> ssize_t write (int fd, const void *buf, size_t count) ;
返回值:成功则返回写入的字节数,失败则返回-1
为什么写入字节数会少于指定数量:
系统对文件的最大长度有限制,或者磁盘空间不足
因此有必要校验是否完全写入
lseek()函数 1 2 3 #include <sys/type.h> #include <unistd.h> off_t oldpos = lseek(int fd , off_t dist , int base)
参数:
dist:移动的距离
base:SEEK_SET -> 文件开始,SEEK_CUR -> 当前位置 , SEEK_END -> 文件结尾
返回值:返回指针变化前的位置,返回-1表示遇到错误
stat()函数 该函数返回关于一个文件的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat (const char *pathname, struct stat *statbuf) ;int fstat (int fd, struct stat *statbuf) ;int lstat (const char *pathname, struct stat *statbuf) ;struct stat { dev_t st_dev; ino_t st_ino; 索引编号 mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; off_t st_size; blksize_t st_blksize; blkcnt_t st_blocks; struct timespec st_atim ; struct timespec st_mtim ; struct timespec st_ctim ; #define st_atime st_atim.tv_sec #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec }; #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask)) #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR) #define S_ISCHR(mode) __S_ISTYPE((mode), __S_IFCHR) #define S_ISBLK(mode) __S_ISTYPE((mode), __S_IFBLK) #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
返回值:如果成功返回0,否则返回-1,并且error会设置为相应的错误类型
ioctl() 用来操作底层设备文件的参数 的系统调用。ioctl 的作用非常强大、灵活。不同的驱动程序内部会实现不同的 ioctl,应用可以使用各种 ioctl 跟驱动程序交互:可以传数据给驱动程序,也可以从驱动程序中读出数据。
1 2 #include <sys/ioctl.h> int ioctl (int fd, unsigned long request, ...) ;
参数:
fd 表示文件描述符;
request 表示与驱动程序交互的命令,用不同的命令控制驱动程序输出我们需要的数据;
… 表示可变参数 arg,根据 request 命令,设备驱动程序返回输出的数据
返回值:
mmap() 1 2 #include <sys/mman.h> void *mmap (void *addr, size_t length, int prot, int flags,int fd, off_t offset) ;
参数:
addr:表示指定映射的內存起始地址,通常设为 NULL 表示让系统自动选定地址,并在成功映射后返回该地址;
length:表示将文件中多大的内容映射到内存中;
prot:表示映射区域的保护方式,可以为以下 4 种方式的组合:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读出
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
flags:表示影响映射区域的不同特性,常用的有以下两种:
MAP_SHARED 表示对映射区域写入的数据会复制回文件内,原来的文件会改变。
MAP_PRIVATE 表示对映射区域的操作会产生一个映射文件的复制,对此区域的任何修改都不会写回原来的文件内容中
fd:被映射的文件描述符
offset:从文件的offset偏移位置开始映射
返回值:
若成功映射,将返回指向映射的区域的指针,失败将返回-1