c语言基础学习10_文件操作01

简介: ==========================================================================================================================================================涉及到的知识点有:一、fopen函数。

=============================================================================
=============================================================================
涉及到的知识点有:
一、fopen函数。
二、fclose函数。
三、getc 和 putc 函数
1、通过getc和putc读写指定的文件、2、拷贝文件的代码。(一个一个字节的拷贝)、
3、改进版的代码:通过命令行参数,实现指定文件名的拷贝、4、文件的加密解密操作。(用getc和putc函数实现)。
四、fgets 和 fputs函数
1、fgets 和 fputs函数、2、拷贝文件的代码。(一行一行字节的拷贝)、3、文件的加密解密操作。(用fgets和fputs函数实现)、
4、课堂练习:超大文件排序、5、解析文件内容并追加结果。
五、fprintf 和 fscanf函数
1、课堂练习:运行的结果是打印出这个文件中年龄第二大人的姓名。
=============================================================================
=============================================================================
文件操作

作为计算机语言,读写文件是一个基本的能力。

一、fopen函数

FILE *  类型在堆里面。
想要操作一个文件,就要首先把文件打开。

FILE *fopen(const char *path, const char *mode);
fopen打开文件成功,返回有效的FILE地址,失败返回NULL。
path就是指定打开文件的路径,可以是相对路径,也可以是绝对路径。

mode有以下几个值:
  r     以只读方式打开文件,该文件必须存在,且文件必须是可读的。
  r+     以可读写方式打开文件,该文件必须存在。
  rb+   读写打开一个二进制文件,允许读写数据,文件必须存在。(b只在windows下有效,在linux下无效。)
  rw+     读写打开一个文本文件,允许读和写。
  w      打开只写文件,若文件存在则文件长度请为0,即该文件内容会消失。
          若文件不存在则建立该文件。
  w+    打开可读写文件,若文件存在则文件长度清为0,即该文件内容会消失。
          若文件不存在则建立该文件。
  a      以附加的方式打开只写文件。若文件不存在,则会建立该文件。
          如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
  a+   以附加的方式打开可读写文件。若文件不存在,则会建立该文件。
         如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(原来的EOF符不保留)

需要包含头文件:#include <stdio.h>
--------------------------------------
二、fclose函数

fclose关闭fopen打开的文件。
只要成功用fopen打开的文件,使用完成后就一定要调用fclose进行关闭。

int fclose(FILE *stream);
close的参数就是fopen的返回值。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     //FILE *p = fopen("./a.txt", "r");  //相对路径。                
 6     //FILE *p = fopen("/home/chen/001/01/文件操作day01/a.txt", "r");  //绝对路径。
 7 
 8     //"/home/chen/001/01/文件操作day01/a.txt"因为这个是字符串常量,所以上面这句等价于下面:
 9     char a[] = "/home/chen/001/01/文件操作day01/a.txt";
10     FILE *p = fopen(a, "r");
11 
12     if (p) 
13     {   
14         printf("success\n");
15         fclose(p);  //文件打开了。
16     }   
17     else
18     {   
19         printf("fail\n");   //这里不需要调用fclsoe,因为文件没有打开成功。
20     }   
21 
22     return 0;
23 }

=============================================================================
三、getc 和 putc 函数

1、int getc(FILE *stream);
getc的参数是fopen成功打开文件返回的指针,getc的返回值是一个char,即一次读一个char。
getc的功能是:以字节为单位读取文件内容。

文本文件的最后结束标示是-1,也就是一个宏EOF。即#define EOF -1
注意:EOF不是文件的一部分内容,只是文件结束的标识而已,所以不要把它输出来。

linux下示例代码如下:

 1 int main()
 2 {
 3     char a[] = "/home/chen/001/01/文件操作day01/a.txt";
 4     FILE *p = fopen(a, "r");
 5 
 6     if (p) 
 7     {   
 8         printf("success\n");
 9         while (1) 
10         {   
11             char c = getc(p);    //从文件p里面一个一个字节的读出。
12             if (c == EOF)
13             {   
14                 break;
15             }   
16             printf("%c", c); 
17         }   
18         fclose(p);  //文件打开了。
19     }   
20     else
21     {   
22         printf("fail\n");   //这里不需要调用fclsoe,因为文件没有打开成功。
23     }   
24 
25     return 0;
26 }
27 --------------------------------------
28 改进版代码:
29 
30 #include <stdio.h>
31 
32 int main()
33 {
34     char a[] = "/home/chen/001/01/文件操作day01/a.txt";
35     FILE *p = fopen(a, "r");
36 
37     if (p) 
38     {   
39         printf("success\n");
40         char c = getc(p);    //从文件p里面一个一个字节的读出。
41         while (c != EOF)
42         {   
43             printf("%c", c); 
44             c = getc(p);
45         }   
46         fclose(p);
47     }   
48     else
49     {   
50         printf("fail\n");   //这里不需要调用fclose。
51     }   
52 
53     return 0;
54 }
55 注意:改进版的代码:EOF不是文件的一部分内容,只是文件结束的标识而已,所以不要把它输出来。

-----------------------------------------------------------------------------
2、int putc(int c, FILE *stream);
第一个参数是:要写入的char;
第二个参数是:fopen返回的文件指针。
注意:getc必须是用r模式打开,putc必须是用w模式打开。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     FILE *p = fopen("./a.txt", "w");
 6     if (p) 
 7     {   
 8         putc('a', p);    //向文件p里面一个一个字节的写入。
 9         putc('b', p);     //向文件p里面一个一个字节的写入。
10         putc('\n', p);     //向文件p里面一个一个字节的写入。
11         fclose(p);
12     }   
13 
14     return 0;
15 }

-----------------------------------------------------------------------------
通过getc和putc读写指定的文件。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main01(int argc, char **args)
 4 {
 5     if (argc < 2)   //a b.txt 
 6     {   
 7         return 0;
 8     }   
 9 
10     FILE *p = fopen(args[1], "w");
11     if (p) 
12     {   
13         while (1) 
14         {   
15             char c = getchar(); //从标准输入设备读取一个字符。
16             if (c == '0')
17             {   
18                 break;
19             }   
20             putc(c, p);    //向文件p里面一个一个字节的写入。
21         }   
22         fclose(p);
23     }   
24 
25     return 0;
26 }
27 
28 int main(int argc, char **args)
29 {
30     if (argc < 2)
31     {   
32         return 0;
33     }   
34 
35     FILE *p = fopen(args[1], "r");
36     if (p) 
37     {   
38         char c = getc(p);    //从文件p里面一个一个字节的读出。
39         while (c != EOF)
40         {
41             printf("%c", c);
42             c = getc(p);
43         }
44         fclose(p);
45     }
46 
47     return 0;
48 }

-----------------------------------------------------------------------------
拷贝文件的代码。(一个一个字节的拷贝)

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     FILE *p = fopen("./a1.c", "r");
 6     FILE *p1 = fopen("./abc.txt", "w");
 7 
 8     if (p1 == NULL)
 9     {   
10         return 0;
11     }   
12     if (p) 
13     {   
14         char c = getc(p);    //从文件p里面一个一个字节的读出。
15         while (c != EOF)
16         {   
17             putc(c, p1);    //从文件p里面每读一个char,就向文件p1里面写一个char。
18             c = getc(p);
19         }   
20         fclose(p);
21         fclose(p1);
22     }   
23 
24     return 0;
25 }

-----------------------------------------------------------------------------
改进版的代码:通过命令行参数,实现指定文件名的拷贝。
例如:mycopy a.txt b.txt,把a.txt拷贝为b.txt了。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 //通过命令行参数,实现指定文件名的拷贝。
 4 int main(int argc, char **args)
 5 {
 6     if (argc < 3)
 7     {
 8         return -1;
 9     }
10     FILE *p = fopen(args[1], "r");
11     FILE *p1 = fopen(args[2], "w");
12 
13     if (p1 == NULL)
14     {   
15         return 0;
16     }   
17     if (p) 
18     {   
19         char c = getc(p);    //从文件p里面一个一个字节的读出。
20         while (c != EOF)
21         {   
22             putc(c, p1);    //从文件p里面每读一个char,就向文件p1里面写一个char。
23             c = getc(p);
24         }   
25         fclose(p);
26         fclose(p1);
27     }   
28 
29     return 0;
30 }

-----------------------------------------------------------------------------
文件的加密解密操作。(用getc和putc函数实现)

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 //命令行有3个参数,第一个是源文件,第二个是目标文件,第三个参数0代表加密,1代表解密。
 4 int main(int argc, char **args)
 5 {
 6     if (argc < 4)
 7     {
 8         return -1;
 9     }
10     FILE *p = fopen(args[1], "r");
11     FILE *p1 = fopen(args[2], "w");
12 
13     if (p1 == NULL)
14     {   
15         return 0;
16     }   
17     if (p) 
18     {   
19         char c = getc(p);    //从p里面一个一个字节的读出。
20         while (c != EOF)
21         {   
22             //这里根据第三个参数决定++还是--。
23             char tmp = args[3][0];
24             if (tmp == 0)
25             {
26                 c++;    //加密。char *fgets(char *s, int size, FILE *stream);
27             }
28             else
29             {
30                 c--;    //解密。
31             }
32             putc(c, p1);    //从文件p里面每读一个char,就向文件p1里面写一个char。
33             c = getc(p);
34         }   
35         fclose(p);
36         fclose(p1);
37     }   
38 
39     return 0;
40 }

=============================================================================
四、fgets 和 fputs函数

这些函数都是通过 FILE * 来对文件进行读写的。

1、fgets 和 fputs函数

fgets的返回值是 char *,代表函数读到的是字符串的首地址,如果fgets到了文件末尾,继续调用的话,则返回NULL。

int fputs(const char *s, FILE *stream);
char *fgets(char *s, int size, FILE *stream);
--------------------------------------
linux下示例代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 //可以通过命令行参数指定文件名。
 5 int main(int argc, char **args)
 6 {
 7     if (argc < 2)
 8     {   
 9         return 0;
10     }   
11     
12     FILE *p = fopen(args[1], "w");
13     if (p) 
14     {   
15         while (1) 
16         {   
17             char buf[1024] = { 0 };
18             fgets(buf, sizeof(buf), stdin);    //从标准输入设备一次性获取buf个字节的数据。
19     
20             if (strncmp(buf, "exit", 4) == 0)
21             {   
22                 break;
23             }   
24             fputs(buf, p);     //向文件p里面一次性写入一个buf个字节的数据。
25         }   
26         fclose(p);
27     }   
28 
29     return 0;
30 }

-----------------------------------------------------------------------------
拷贝文件的代码。(一行一行字节的拷贝)

EOF 与 feof 函数

运行程序后,怎么才能知道是否已经到达文件结尾了呢?EOF代表文件结尾。

如果已经是文件尾,则调用函数feof返回true。

int feof(FILE *stream);
函数的形参是fopen返回的文件指针。

EOF不属于文件的内容,只是文件的结尾标示,而且也不要直接用-1来代替EOF。

只有文本文件才能通过EOF判断文件的结尾标示,对于二进制文件EOF是无效的。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main(int argc, char **args)
 4 {
 5     if (argc < 3)
 6     {   
 7         return 0;
 8     }   
 9 
10     FILE *p = fopen(args[1], "r");  //r 以只读方式打开文件,该文件必须存在,且文件必须是可读的。
11     if (p == NULL)
12     {   
13         return 0;
14     }   
15 
16     FILE *p1 = fopen(args[2], "w"); //w 打开只写文件,若文件存在则文件长度请为0,即该文件内容会消失。 若文件不存在则建立该文件。
17     if (p1 == NULL)
18     {   
19         return 0;
20     }   
21 
22     while (!feof(p))    //这句话的意思是:只要没有到文件的结尾,那么循环就继续。
23     {   
24         char buf[1024] = { 0 };
25         fgets(buf,sizeof(buf), p);  //从源文件p中读取一行。
26         fputs(buf, p1);             //向目标文件p1中写入一行。
27 
28         //printf("%s", buf);        //打印看看效果。
29     }   
30 
31     fclose(p);
32     fclose(p1);
33 
34     return 0;
35 }

-----------------------------------------------------------------------------
文件的加密解密操作。(用fgets和fputs函数实现)

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 //加密。
 4 void decode(char *s) 
 5 {
 6     int len = 0;
 7     while (s[len])
 8     {   
 9         s[len]++;
10         len++;
11     }   
12 }
13 //解密。
14 void encode(char *s) 
15 {
16     int len = 0;
17     while (s[len])
18     {   
19         s[len]--;
20         len++;
21     }   
22 }
23 
24 int main(int argc, char **args)
25 {
26     if (argc < 4)
27         return 0;
28 
29     FILE *p1 = fopen(args[1], "r");
30     if (p1 == NULL)
31         return 0;
32     
33     FILE *p2 = fopen(args[2], "w");
34     if (p2 == NULL)
35         return 0;
36 
37     while (!feof(p1))
38     {
39         char buf[1024] = { 0 };
40         fgets(buf, sizeof(buf), p1);
41 
42         if (args[3][0] == '0')
43             decode(buf);
44 
45         if (args[3][0] == '1')
46             encode(buf);
47 
48         fputs(buf, p2);
49     }
50     fclose(p1);
51     fclose(p2);
52 
53     return 0;
54 }
55 chen@iZ2zeeailqvwws5dcuivdbZ:~/001/01/文件操作day01$ a a2.c aa.c 0    加密
56 chen@iZ2zeeailqvwws5dcuivdbZ:~/001/01/文件操作day01$ cat aa.c
57 chen@iZ2zeeailqvwws5dcuivdbZ:~/001/01/文件操作day01$ a aa.c aaa.c 1    解密
58 chen@iZ2zeeailqvwws5dcuivdbZ:~/001/01/文件操作day01$ cat aaa.c 

=============================================================================
课堂练习:超大文件排序。
课堂练习:给很大的a.txt内容排序,但不能用堆,只能用栈,排完序的内容要放回a.txt。(文件的每一行是随机数)

linux下示例代码如下:

 1 //用随机数生成100个0到255之间的数,每个数为一行存放在a.txt中。
 2 #include <stdio.h>
 3 #include <time.h>
 4 #include <stdlib.h>
 5 
 6 int main()
 7 {
 8     srand((unsigned int)time(NULL));
 9 
10     FILE *p = fopen("a.txt", "w");
11     
12     if (p) 
13     {   
14         int i;
15         for (i = 0; i < 100; i++)
16         {   
17             int seq = rand() % 256;
18             char buf[100] = { 0 };//把int转化成字符串。
19             sprintf(buf, "%d\n", seq);//sprintf使用方法与printf类似,唯一的区别是多了第一个参数,第一个参数是一个char的数组。
20             fputs(buf, p); 
21         }   
22         fclose(p);
23     }   
24 
25     return 0;
26 }

-----------------------------------------------------------------------------
//将产生的a.txt进行排序。

linux下示例代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 void swap(int *a, int *b) 
 5 {
 6     int tmp = *a; 
 7     *a = *b; 
 8     *b = tmp;
 9 }
10 
11 void bubble(int *a, int n)
12 {
13     int i, j;
14     for (i = 0; i < n; i++)
15     {   
16         for (j = 1; j < n - i; j++)
17         {   
18             if (a[j - 1] > a[j])
19             {   
20                 swap(&a[j - 1], &a[j]);
21             }   
22         }   
23     }   
24 }
25 
26 int main()
27 {
28     FILE *p = fopen("./a.txt", "r");
29     
30     int array[100] = { 0 };
31     int index = 0;
32     while (!feof(p))
33     {   
34         char buf[1024] = { 0 };
35         fgets(buf, sizeof(buf), p); 
36     
37         //把读出来的字符串转化为整数,并存在数组array中。
38         array[index] = atoi(buf);
39         index++;
40     }
41     fclose(p);
42 
43     //给数组进行冒泡排序。
44     bubble(array, 100);
45 
46     p = fopen("./a.txt", "w");
47     int i;
48     for (i = 0; i < 100; i++)
49     {
50         char buf[1024] = { 0 };
51         sprintf(buf,"%d\n", array[i]);
52         fputs(buf, p);
53     }
54     fclose(p);
55 
56     return 0;
57 }

-----------------------------------------------------------------------------
冒泡排序:适合要排序的数量比较少的。如果数据量比较大的话,就不适合了。
--------------------------------------
c语言中,数组a[i++]和数组a[++i]有区别吗?

b = a++; //先计算表达式的值,即先把a赋值给了b;然后a再自加1。
b = ++a; //先a自加1后;然后把a自加后得到的赋值给b。
小结:谁在前面先计算谁!!!

a[i++]; //相当于a[i]; i=i+1;
a[++i]; //相当于a[i+1]; i=i+1;

有区别,举例说明:

 1 #include <stdio.h>
 2 
 3 int main ()
 4 {
 5     int a[3] = {1,2,3};
 6     int i = 0;
 7     printf("%d\n",a[i++]);//输出的值为1,因为是i++,所以是先使用a[0]的值,i再加上1,即先输出a[0]的值。
 8     
 9     i = 0;
10     printf("%d\n",a[++i]);//输出的值为2,因为++i,所以先直接使i加1,再输出a[1]的值。
11     
12     return 0;
13 }

--------------------------------------
在c语言中,数组a[0]++是什么意思?
a[0]表示数组中的第一个值,可以把它看成一个变量x,
a[0]++也就是数组中第一个值+1再存放到原位。
比如:int a[2];
其中a[0]=1; a[1]=5;
a[0]++以后,a[0]的值变为2。
--------------------------------------
超大文件排序示例代码:

linux下示例代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()
 5 {
 6     FILE *p = fopen("a.txt", "r");
 7 
 8     int array[256] = { 0 } ; 
 9     while (!feof(p))
10     {   
11         char buf[1024] = { 0 };
12         fgets(buf, sizeof(buf), p); 
13         int a = atoi(buf);
14         array[a]++;
15     }   
16     fclose(p);
17     
18     p = fopen("a.txt", "w");
19     int i, j;
20     for (i = 0; i < 256; i++)
21     {   
22         for (j = 0; j < array[i]; j++)
23         {   
24             char buf[1024] = { 0 };
25             sprintf(buf, "%d\n", i); 
26             fputs(buf, p); 
27         }   
28     }   
29     fclose(p);
30 
31     return 0;
32 }
33 
34 array[a]++;
35 该句代码的解释如下:
36 
37 a[0] = 5
38 a[1] = 3
39 a[2] = 0
40 a[3] = 10
41 
42 0在文件中出现5次
43 1出现3次
44 2出现0次
45 3出现10次

=============================================================================
解析文件内容并追加结果。

a.txt文件中中可能有1行,也可能有1w行,每行的格式是固定的。
且a.txt中的每一行数据的格式是:整数运算符整数=
即:
34*5=
25+41=
65/5=
78-41=
......
要求写个程序,运行的结果是在a.txt文件中每行后面自动添加计算结果,
可以用堆,也可以用栈,但只能有a.txt这一个文件,不能再生成其他新的文件。
--------------------------------------
linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int func1(int a, char b, int c)
 4 {
 5     switch (b) 
 6     {   
 7         case '+':
 8             return a + c;
 9         case '-':
10             return a - c;
11         case '*':
12             return a * c;
13         case '/':
14             if (c != 0)
15             {   
16                 return a / c;
17             }   
18     }   
19     return 0;
20 }
21 
22 int main()
23 {
24     FILE *p = fopen("a.txt", "r");
25     
26     char array[100][100] = { 0 };
27     int index = 0;
28     while (1) 
29     {   
30         char buf[1024] = { 0 };
31         fgets(buf, sizeof(buf), p); //假设文件读到最后一行输出后,其文件已经读完了。但是feof需要再判断一次。
32     
33         //已经到了最后一行,此时调用feof,feof函数返回true。
34         if (feof(p))
35         {   
36             break;
37         }   
38     
39         int a = 0;
40         char b = 0;
41         int c = 0;
42         sscanf(buf, "%d%c%d=", &a, &b, &c);
43         //printf("%d%c%d=%d\n", a, b, c, func1(a, b, c));       //格式化字符串函数sprintf(输出)、格式化字符串函数sscanf(读取输入)。
44         sprintf(array[index], "%d%c%d=%d\n", a, b, c, func1(a, b, c));
45         index++;
46     }
47     fclose(p);
48 
49     p = fopen("a.txt", "w");
50     int i;
51     for (i = 0; i < index; i++)
52     {
53         fputs(array[i], p);
54     }
55     fclose(p);
56 
57     return 0;
58 }

-----------------------------------------------------------------------------
//以上代码只能处理100行的文件。用栈不行,那就用堆!

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int func1(int a, char b, int c)
 5 {
 6     switch(b)
 7     {
 8     case '+':
 9         return a + c;
10     case '-':
11         return a - c;
12     case '*':
13         return a * c;
14     case '/':
15         if (c != 0)
16             return a / c;
17     }
18     return 0;
19 }
20 
21 #define NUM 100
22 
23 int main()
24 {
25     FILE *p = fopen("a.txt", "r");
26     
27     //char array[100][100] = { 0 };
28     char *array = calloc(NUM, sizeof(char));
29     char *tmp = array;    //代表当前要写入字符的位置。
30     int index = 0;
31     while(1)
32     {
33         char buf[100] = { 0 };
34         fgets(buf, sizeof(buf), p); //假设文件读到最后一行输出后,其文件已经读完了。但是feof需要再判断一次。
35         
36         //已经到了最后一行,此时调用feof,feof函数返回true。
37         if (feof(p))
38             break;
39         
40         int a = 0;
41         char b = 0;
42         int c = 0;
43         sscanf(buf, "%d%c%d=", &a, &b, &c);
44         //printf("%d%c%d=%d\n", a, b, c, func1(a, b, c));    //格式化字符串函数sprintf(输出)、格式化字符串函数sscanf(读取输入)。
45         //sprintf(array[index], "%d%c%d=%d\n", a, b, c, func1(a, b, c));
46         //sprintf(array, "%d%c%d=%d\n", a, b, c, func1(a, b, c));
47         sprintf(tmp,"%d%c%d=%d\n", a, b, c, func1(a, b, c));
48         array = realloc(array, NUM * (index + 2));    //array永远指向堆内存的首地址。
49         tmp = array + (NUM * (index + 1));    //tmp每次往后移动100个字节。
50         index++;
51     }
52     fclose(p);
53     p = fopen("a.txt", "w");
54     int i;
55     tmp = array;    //让tmp回到起始位置。
56     for(i = 0; i < index; i++)
57     {
58         //fputs(array[i], p);
59         fputs(tmp, p);
60         tmp += NUM;
61     }
62     fclose(p);
63     free(array);
64 
65     return 0;
66 }

=============================================================================
五、fprintf 和 fscanf函数

  fscanf从一个文件中读取我想要的内容。即从一个文件中读取内容并转义。
  sscanf从一个字符串中读取我想要的内容。即从一个字符串中读取内容并转义。

  fprintf向一个文件进行输出。
  sprintf向一个字符串进行输出。

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int func1(int a, char b, int c)
 4 {
 5     switch(b)
 6     {   
 7         case '+':
 8             return a + c;
 9         case '-':
10             return a - c;
11         case '*':
12             return a * c;
13         case '/':
14             if (c != 0)
15                 return a / c;
16     }   
17     return 0;
18 }
19 
20 int main()
21 {
22     FILE *p = fopen("a.txt", "r");
23     FILE *p1 = fopen("b.txt", "w");
24 
25     while (1) 
26     {   
27         int a = 0;
28         char b = 0;
29         int c = 0;
30         fscanf(p, "%d%c%d=", &a, &b, &c);
31         if (feof(p))
32             return 0;
33 
34         //printf("%d, %c, %d\n", a, b, c);
35         fprintf(p1,"%d%c%d=%d\n", a, b, c, func1(a, b, c));
36     }   
37     fclose(p);
38     fclose(p1);
39 
40     return 0;
41 }

-----------------------------------------------------------------------------
课后练习
姓名=刘德华,年龄=50
姓名=安倍,年龄=30
姓名=张学友,年龄=45

用c语言写程序,其实就是针对内存的每个字节进行操作。
也就是说我们若是知道每个内存里面每个字节是什么东西的话,那么我们就可以自由的进行操作的。

linux下示例代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 int main()
 6 {
 7     FILE *p = fopen("a.txt", "r");
 8 
 9     while (1) 
10     {   
11         char buf[1024] = { 0 };
12         fgets(buf, sizeof(buf), p); 
13     
14         if (feof(p))
15         {   
16             break;
17         }   
18         char *s = strtok(buf, ",");     //字符串分割函数strtok。注意:在第二次至以后调用strtok函数时,第一个参数写NULL。
19         char *name = strchr(s, '=');    //字符串查找字符函数strchr。
20         //printf("%s\n", s);
21         //printf("%s\n", name);
22         printf("%s\n", &s[7]);
23         //printf("%s\n", &name[1]);
24 
25         s = strtok(NULL, ",");
26         //printf("%s", s);  //年龄=50   在UTF-8情况下,每个汉字占用3个字节。
27         //printf("%s", &s[7]);          //字符串转化为int类型。
28         printf("%d\n", atoi(&s[7]));
29     }   
30     fclose(p);
31 
32     return 0;
33 }
34 输出结果为:
35 刘德华
36 50
37 安倍
38 30
39 张学友
40 45

-----------------------------------------------------------------------------
课后练习
姓名=刘德华,年龄=50
姓名=安倍,年龄=30
姓名=张学友,年龄=45

运行的结果是打印出这个文件中年龄第二大人的姓名。

先来复习下一维数组中找第二元素的代码:

linux下示例代码如下:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int a[5] = { 12, 45, 56, 13, 98 };
 6     int max = 0;
 7     int smax = 0;
 8 
 9     int i;
10     for (i = 0; i < 5; i++)
11     {   
12         if (a[i] > max)
13         {   
14             smax = max;
15             max = a[i];
16         }   
17         else if (a[i] < max && a[i] > smax)
18         {   
19             smax = a[i];
20         }   
21     }   
22     printf("%d\n", smax);
23 
24     return 0;
25 }

--------------------------------------
linux下示例代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 int main()
 6 {
 7     FILE *p = fopen("a.txt", "r");
 8     
 9     int max = 0;
10     int smax = 0;
11     char max_name[100] = { 0 };
12     char smax_name[100] = { 0 };
13 
14     while (1) 
15     {   
16         char buf[1024] = { 0 };
17         fgets(buf, sizeof(buf), p); 
18     
19         if (feof(p))
20         {   
21             break;
22         }   
23         char *s = strtok(buf, ",");     //字符串分割函数strtok。注意:在第二次至以后调用strtok函数时,第一个参数写NULL。
24         char *name = strchr(s, '=');    //字符串查找字符函数strchr。
25         //printf("%s\n", s);
26         //printf("%s\n", name);
27         //printf("%s\n", &s[7]);
28         //printf("%s\n", &name[1]);
29 
30         s = strtok(NULL, ",");
31         //printf("%s", s);  //年龄=50   在UTF-8情况下,每个汉字占用3个字节。
32         //printf("%s", &s[7]);          //字符串转化为int类型。
33         //printf("%d\n", atoi(&s[7]));
34 
35         if (atoi(&s[7]) > max)
36         {   
37             smax = max;
38             max = atoi(&s[7]);
39 
40             strcpy(smax_name, max_name);
41             strcpy(max_name, &name[1]);
42         }   
43         else if (atoi(&s[7]) < max && atoi(&s[7]) > smax)
44         {
45             smax = atoi(&s[7]);
46 
47             strcpy(smax_name, &name[1]);
48         }
49     }
50     fclose(p);
51 
52     printf("%s\n", smax_name);
53 
54     return 0;
55 }

=============================================================================

我的GitHub地址: https://github.com/heizemingjun
我的博客园地址: http://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】
相关文章
|
4月前
|
存储 编译器 程序员
c语言的文件操作与文件缓冲区
如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。磁盘(硬盘)上的文件是文件。但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从文件功能的角度来分类 的)。就比如说我们电脑中以.txt为后缀的就是文件的一种,他就是数据文件。.exe为后缀的就为程序文件。函数名功能适用范围fgetc字符输入函数所有输入流fputc字符输出函数所有输出流fgets。
102 0
|
8月前
|
人工智能 C语言
|
9月前
|
存储 小程序 C语言
【C语言程序设计——文件】文件操作(头歌实践教学平台习题)【合集】
本文介绍了C语言中的文件操作,分为两个关卡。第1关任务是将键盘输入的字符(以#结束)存入`file1.txt`并显示输出;第2关任务是从键盘输入若干行文本(每行不超过80个字符,用-1作为结束标志),写入`file2.txt`后再读取并显示。文中详细讲解了文件的打开、读取(使用`fgetc()`和`fgets()`)、写入(使用`fputc()`和`fputs()`)及关闭操作,并提供了示例代码和测试说明。
235 5
|
10月前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
289 9
|
10月前
|
存储 数据管理 C语言
C 语言中的文件操作:数据持久化的关键桥梁
C语言中的文件操作是实现数据持久化的重要手段,通过 fopen、fclose、fread、fwrite 等函数,可以实现对文件的创建、读写和关闭,构建程序与外部数据存储之间的桥梁。
|
11月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
608 3
|
11月前
|
存储 C语言
【c语言】玩转文件操作
本文介绍了C语言中文件操作的基础知识,包括文件的打开和关闭、文件的顺序读写、文件的随机读写以及文件读取结束的判定。详细讲解了`fopen`、`fclose`、`fseek`、`ftell`、`rewind`等函数的使用方法,并通过示例代码展示了如何进行文件的读写操作。最后,还介绍了如何判断文件读取结束的原因,帮助读者更好地理解和应用文件操作技术。
214 2
|
12月前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
12月前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
12月前
|
存储 C语言
C语言文件操作(2)
【10月更文挑战第2天】
79 6