C语言从头学65—学习头文件 <stdio.h>(一)

时间:2024-10-09 11:37:24

       stdio.h是我们接触最早的头文件,用于读取和写入文件,也用于控制台的输入和输出。这个头文件中的《标准 I/O 函数》、《文件操作函数》、《字符串操作函数》前面已经学习过。这里继续学习一些没有使用过的函数。
 1、函数tmpfile()
      功能:这个函数可以创建一个临时文件,该文件只在程序运行期间存在,程序运行结束文件被自动删除;当调用fclose()函数时,程序虽未结束该文件也将被自动删除。
      使用格式:tmpfile(); //无参
      返回值:返回FILE*类型的文件指针
      说明:
        a.创建的临时文件的格式为wb+模式。(二进制写读)
        b.通过使用FILE*类型的文件指针接收返回值后,即可象正常文件一样使用这个文件,只是这个文件的文件名不知道,而且程序结束后就找不到了。
 2、函数tmpnam()
       功能:该函数生成一个具有唯一文件名的临时文件。
       使用格式:tmpnam(参1);
           参1:字符串指针变量(接收临时文件名)
       返回值:成功返回指向该字符串变量的指针;失败返回空指针NULL。
       说明:
         a.生成的临时文件名有多少字符事先不知道,那么应当声明多少字节的字符串接收
        这个文件名呢?长度可以使用这个宏L_tmpnam定义即可。
         b.收到文件名后,可以使用文件操作函数对其进行操作。
         c.上面两个函数的区别主要是有无文件名,其它方面都一样,程序结束或调用fclose都会即刻被删除掉。
 3、函数fflush()
       功能:用于清空缓存区,将缓冲区的内容存入文件。
       使用格式“:fflush(参1);
           参1:文件指针(也可以是输出设备,如屏幕stdout)
       返回值:清空成功返回0,否则返回EOF。
       说明:
        a.如不需要保存缓存区内容,则参1为NULL。
        b.缓冲区的运行是有规则的,一般够一定数量才进行写操作,这个函数的作用就是不等凑足一批,而是立即强制性地清空输出缓存区(比如写入文件)。
 4、函数setvbuf()
      功能:定义缓冲区模式
      使用格式:setvbuf(参1,参2,参3,参4);
          参1:文件指针
          参2:缓冲区指针
          参3:缓存的行为模式,有三个宏,分别是:
                   _IOFBF :满缓存(默认值,即缓存空了才读,缓存满了才写)
                   _IOLBF :行缓存。(一行一读,一行一写)
                   _IONBF :无缓存。(不使用缓存区)
          参4:缓存区的大小。(默认缓冲区大小使用宏BUFSIZ)
       返回值:返回类型为int型,成功返回值为0 ,失败返回非零值。
       说明:
        a.使用函数setvbuf()定义缓冲区模式,应在打开文件之后进行;
        b.如果参2使用NULL,则函数setvbuf()会自动创建一个缓冲区。
 5、函数ungetc()
      功能:将从缓存里面读取的字符重新放回缓存,再次读取时将从这个字符开始。
      使用格式:ungetc(参1,参2);
         参1:int型字符变量
         参2:文件指针
      返回值:成功返回放回缓存的那个字符,失败返回EOF(-1)。
 6、函数perror()
       功能:在标准报错误信息前添加一个自定义字符串信息
       使用格式:perror(参1);

 7、验证程序:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h> //Sleep函数需用
#include<math.h>
int main(void)
{
//实验tmpfile()
    FILE* temp = tmpfile();
      //调用tmpfile函数生成临时文件并用FILE*变量接收文件指针
    if (temp == NULL)return 0;
    int a[10] = { 11,25,36,58,14,17,22,65,45,55 };
      //声明int型数组并赋初值
    fwrite(a, sizeof(int), 10, temp);
      //将int数组内容存入临时文件
    rewind(temp);
      //重置临时文件内部指针
    int b[10];
    fread(b,sizeof(int),10,temp);
      //将临时文件中的数据读出存入int数组b[10]
    for (int i = 0; i < 10; i++)
    {
        printf(" %d", b[i]);//运行结果: 11 25 36 58 14 17 22 65 45 55
    }
    printf("\n");
    fclose(temp);
//实验函数tmpnam()
    char filename[L_tmpnam];
      //声明接收临时文件名的字符串变量
    tmpnam(filename);
      //生成临时文件(名)
    printf("生成的临时文件名:%s\n", filename);
    FILE* temp2 = fopen(filename, "wb+");
      //以二进制写读方式打开临时文件
    fwrite(a, sizeof(int), 10, temp2);
      //将前面的int数组a写入临时文件
    rewind(temp2);
      //重置临时文件内部指针
    fread(b, sizeof(int), 10, temp2);
      //将临时文件中的内容读取到数组b中
    for (int i = 0; i < 10; i++)
    {
        printf(" %d", b[i]);//运行结果: 11 25 36 58 14 17 22 65 45 55
    }
    printf("\n");
    fclose(temp2);
//实验函数fflush()
    for (int i = 0; i <10; i++)
    {
        printf("  %d", i);
        fflush(stdout); //每循环一次立即将结果发送到屏幕
        Sleep(50);
    }
    printf("\n");
//实验函数setvbuf()
    FILE * pFile = fopen("temp.txt", "wb+");
    char myBuffer[1024] = {0};
    setvbuf(pFile, myBuffer, _IOLBF, 1024);
//实验ungetc()
    //利用前面的pFile
    char ch[] = "abcdefghijklmn";
    fwrite(ch, sizeof(char), sizeof(ch) / sizeof(char), pFile);
    rewind(pFile);
    int c = getc(pFile);
    if (!isdigit(c))printf("读取的不是数字,已放回缓冲区\n");
    ungetc(c,pFile);
//实验perror()
    errno = 0;
    double x = sqrt(-1);
    if(errno==0)printf("x=%f\n", x); //结果不再显示
    perror("sqrt函数异常..."); //报错信息:sqrt函数异常...: Domain error

    getchar();
    return 0;
}