C语言中的一些函数

本文介绍了C语言中的一些重要函数,包括退出处理函数exit()和_exit(),alarm定时器,system命令执行,atexit登记函数,sprintf和printf的用法,以及fgets的文件读取功能。讲解了这些函数的工作原理和实际应用示例。
摘要由CSDN通过智能技术生成

C语言中的一些函数

1. 退出处理函数之exit() 与 _exit() 函数

正常情况下,进程终止,文件关闭,缓冲区的内容会被写到内核。
exit 会先执行一些清除处理,然后进入内核,清除操作包括执行各种终止处理程序,关闭所有标准 I/O 流,_exit会直接进入内核

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
   
int main()
{   
     printf("hello");
     exit(0);
     return 0;
}

打印出hello

lh@ubuntu:~/1231$ ./a.out

hellolh@ubuntu:~/1231$

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
  
int main()
{
     printf("hello");
     _exit(0);
     return 0;
}

什么都不打印

lh@ubuntu:~/1231$ ./a.out

lh@ubuntu:~/1231$

2. alarm 定时函数

alarm 定时,产生一个中断终止程序。

alarm 也称为闹钟函数,它可以再进程中设置一个定时器,当到达定时器指定的时间,它向进程发送 SIGALARM 信号。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。

当在调用 alarm() 前已经设置了一个闹钟,那么我们可以调用**alarm(0)**来取消此闹钟,并返回剩余时间.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int ret;
    ret = alarm(3);
    while(1)
    {
	    //延时1s
        sleep(1);  
        //usleep() 微秒延时
        printf("one second passed\n");
    }
}

运行
one second passed
one second passed
闹钟

3. system 函数

system函数执行一个系统命令,这里是清屏操作。

#include <stdio.h>
#include <unistd.h>
  
int main()
{
      system("clear");
      printf("helloworld\n");
      return 0;
}

运行
helloworld
lh@ubuntu:~/1231$

#include <stdio.h>
#include <unistd.h>
   
int main()
{
     char cmd [] = {"/bin/ls -l"};
     system(cmd);
     return 0;
}

运行
效果相当于在shell中输入ls -l命令

4. 退出处理函数与登记函数 atexit

一个进程可以登记多至 32 个函数,这些函数将 由exit自动调用,atexit 的参数是一个函数地址,调用此函数时无需向它传送任何参数,也不期望它返回一个值,exit以登记这些函数的 相反顺序 调用它们,类似栈,先登记的后处理。

#include <stdlib.h>
#include <stdio.h>
  
static void my_exit1(void)
{
    printf("first exit handler \n");
}
static void my_exit2(void)
{
    printf("second exit handler \n");
}
  
int main(void)
{
    //进行函数登记
    if(atexit(my_exit2)!=0)
        printf("can't register myexit2\n");
    if(atexit(my_exit1)!=0)
        printf("can't register myexit1");
    printf("main is done \n");
    return 0;
}

main is done
first exit handler
second exit handler

5. sprintf 函数

sprintf 与 printf 函数的区别:二者功能相似,但是输出的位置不同,sprintf 函数打印到 字符串 (字符数组),而 printf 函数打印输出到 屏幕 上。

sprintf 函数在我们完成其他数据类型转换成字符串类型的操作中应用广泛。只要在 printf 中可以使用的格式化字符串,在 sprintf 都可以使用。其中的格式化字符串是此函数的精华。

#include <stdio.h>
int main()
{
    char buf[50];
    sprintf(buf,"%d",500);
    printf("%s\n",buf);
}

lh@ubuntu:~/1230$ ./a.out
500

#include <stdio.h>

int main()
{
    char buf[50];
  
    sprintf(buf,"0x%x",500);
    printf("%s\n",buf);
}

lh@ubuntu:~/1230$ ./a.out
0x1f4

#include <stdio.h>
int main()
{
    char buf[50];
    sprintf(buf,"%s love %s","I","YOU");
   
     printf("%s\n",buf);
}

lh@ubuntu:~/1230$ ./a.out
I love YOU

6. printf 函数与 \n

系统有一个缓冲区的机制,printf 函数只有当 buffer 缓冲区满或者有 \n 时才会输出内容。当然程序结束的时候也会输出。

#include <stdio.h>
  int main()
  {
      printf("hello");
   
      while(1)
      {
          ;
      }
  }

没有输出

#include <stdio.h>
  int main()
  {
      printf("hello");
   
       while(1)
       {
           ;
       }
  }

lh@ubuntu:~/1230$ ./a.out
hello
//光标在此行闪烁

7. fgets 函数

char *fgets(char *buf, int bufsize, FILE *stream);

fgets 函数,从文件结构体指针 stream 中读取数据,每次读取一行。读取的数据保存在 buf 指向的字符数组中,每次最多读取 bufsize-1 个字符(第 bufsize 个字符赋'\0')。

  • 如果文件中的该行,不足 bufsize 个字符,则读完该行就结束。
  • 如若该行(包括最后一个换行符)的字符数超过 bufsize-1 ,则 fgets 只返回一个 不完整 的行,但是,缓冲区 buf 总是以 NULL 字符结尾,对 fgets 的下一次调用会继续读该行。函数成功将返回 buf ,失败或读到文件结尾返回 NULL 。因此我们不能直接通过 fgets 的返回值来判断函数是否是出错而终止的,应该借助 feof 函数或者 ferror 函数来判断。

下面是验证程序:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define BUFSIZE 1024

int main()
{
    FILE *fp;
    char *cmd = "printenv";           //printenv可以打印所有的环境变量,在这里只打印包含PATH的变量
    char buf[BUFSIZE];
    buf[BUFSIZE-1] = '\0';
    if((fp=popen(cmd,"r")) == NULL)  
    { 
	    //管道中数据流的方向是由第二个参数控制的,可以是r或w,这里是r,
        perror("popen");              //管道会以读的方式打开
	}
    while((fgets(buf,BUFSIZE,fp)) != NULL)
    {
        if(strstr(buf,"PATH"))        //strstr函数是检查buf中是否有“PATH”
        {
            printf("%s",buf);
        }
    }
    pclose(fp);
    exit(0);
}

lh@ubuntu:~/0102$ ./a.out //红色PATH是为了观看方便加的,实际结果是灰色
MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path
DEFAULTS_PATH=/usr/share/gconf/gnome.default.path
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

将 BUFSIZE 的值修改为 10

_PATH=/usPATH=/usrPATH=/usrlh@ubuntu:~/libingxuan$ //长度都是9

在 BUFSIZE 修改为 10 的基础上将 strstr 函数注释掉

LESSOPEN=| /usr/bin/lesspipe %s
GDM_KEYBOARD_LAYOUT=us
USER=lh
SSH_AGENT_PID=1580
SHLVL=1
ORBIT_SOCKETDIR=/tmp/orbit-lh
OLDPWD=/home/lh
HOME=/home/lh
DESKTOP_SESSION=gnome
XDG_SESSION_COOKIE=bc16201ab626f343740e28ba509d143a-1533265571.786839-1264316423
GTK_MODULES=canberra-gtk-module
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-kcQlVyD6nD,guid=f6f94cf8927fa974e0019d835b63c6a4
COLORTERM=gnome-terminal
GNOME_KEYRING_CONTROL=/tmp/keyring-yTUgGP
MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path
GTK_IM_MODULE=ibus
LOGNAME=lh
_=./a.out
WINDOWID=67108867
DEFAULTS_PATH=/usr/share/gconf/gnome.default.path
USERNAME=lh
TERM=xterm
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
GDM_LANG=zh_CN.utf8
SESSION_MANAGER=local/ubuntu:@/tmp/.ICE-unix/1268,unix/ubuntu:/tmp/.ICE-unix/1268
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
DISPLAY=:0.0
LANG=zh_CN.utf8

可以得出结论 fgets 当待读取一行的长度大于缓冲区时,会读取 BUFSIZE-1 的长度,之后如果还进行 fgets 操作会从上次读取的位置继续读,直到遇到 ‘\n’。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值