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 }
=============================================================================
【转载文章务必保留出处和署名,谢谢!】