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

=============================================================================
=============================================================================
涉及到的知识点有:
一、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 }

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

posted @ 2018-01-25 16:29  黑泽君  阅读(396)  评论(0编辑  收藏  举报