61. 解析linux密码配置文件,获取配置文件信息,每行归纳为一个指针数组存入内存, 练习文件,数组,指针,字符串处理相关的配合使用要点

要求把文件中每行信息分为一组,将一组分割为多个字段存储到内存中。

 

要求把文件中每行信息里的多个字段分割后存入内存。

存储方式如图所示,
1.使用一个指针数组管理每一行中的所有字段,指针数组内每个元素均为每个字段在内存中的首地址。

2.再使用一个指针数组管理所有行。

版本1:还不错

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 int main(void)
 5 {
 6     FILE* fp = fopen("G:/qtcode/passwd","r");
 7     if(fp == NULL)
 8     {
 9         printf("open error
");
10         exit(-1);
11     }
12     char buf[1024]={0};
13 
14     int lineCount = 0;
15     while(fgets(buf,sizeof(buf),fp))
16     {
17         lineCount++;
18     }
19     rewind(fp);
20 
21     char*** storage = (char***)malloc(sizeof(char**) * lineCount);
22     int i,j;
23     for(i = 0;fgets(buf,sizeof(buf),fp);i++)
24     {
25         *(storage+i) = (char**)malloc(sizeof(char*));
26         char* str;
27         for(j = 0,str = buf;str = strtok(str,":");j++,str = NULL)
28         {
29           //在当前行中,只要发现一个小字段,就对指针数组扩容一次
30           //*(storage+i) =  (char**)realloc(*(storage+i),(j+1)*sizeof(char*));
31             *(*(storage+i)+j) = (char*)malloc(strlen(str)+1);
32             strcpy(*(*(storage+i)+j),str);
33             //这条代码放最后边,结束循环时给最后一个char*元素置0,方便以后遍历
34             *(storage+i) =  (char**)realloc(*(storage+i),(j+2)*sizeof(char*));
35         }
36         *(*(storage+i)+j) = NULL;
37     }
38     fclose(fp);
39 
40 //打印
41     for(i = 0;i<lineCount;i++)
42     {
43         for(j = 0;*(*(storage+i)+j);j++)
44         {
45             printf("%s
",*(*(storage+i)+j));
46         }
47     }
48 
49 //释放内存
50     for(i = 0;i<lineCount;i++)
51     {
52         for(j = 0;*(*(storage+i)+j);j++)
53         {
54             free( *(*(storage+i)+j));
55         }
56         free(*(storage+i));
57     }
58 
59     return 0;
60 }



版本2: 很搓

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 int main(void)
 5 {
 6     FILE* fp = fopen("G:/qtcode/passwd","r");
 7     if(fp == NULL)
 8     {
 9         printf("open error
");
10         exit(-1);
11     }
12     char buf[1024]={0};
13 
14     int lineCount = 0;
15     while(fgets(buf,sizeof(buf),fp))
16     {
17         lineCount++;
18     }
19     rewind(fp);
20 
21     char*** storage = (char***)malloc(sizeof(char**) * lineCount);
22     int i,j;
23     for(i = 0;fgets(buf,sizeof(buf),fp);i++)
24     {
25         char* str;
26         int countOfStr;
27         char bufTmp[1024];
28         strncpy(bufTmp,buf,sizeof(bufTmp)-1);
29         bufTmp[strlen(buf)-1] = '';//之前写的-2是为了去回车,感觉先不去了。就把空格+回车当成一个字段算了。而且最后一行结尾没换行,不统一。
30         for(countOfStr = 0,str = bufTmp;str = strtok(str,":");countOfStr++,str = NULL);
31         printf("count = %d
",countOfStr);
32 
33         *(storage+i) = (char**)malloc(sizeof(char*)*(countOfStr+1));//最后一个冒号后边还有一个空格+换行,也算成一个字段。
34                                                               //注意最后一行结尾没换行,很烦。
35                                                              //但是浪费了(总行数-1)*sizeof(char*)个空间
36 
37         for(j = 0,str = buf;str = strtok(str,":") ;j++,str = NULL)
38         {
39 
40            *(*(storage+i)+j) = (char*)malloc(strlen(str)+1);
41             strcpy(*(*(storage+i)+j),str);
42         }
43         putchar(10);
44     }
45     fclose(fp);
46 
47 
48 //打印
49     for(i = 0;i<lineCount;i++)
50     {
51         for(j = 0;j<7;j++)
52         {
53             printf("%s
",*(*(storage+i)+j));
54         }
55         putchar(10);
56     }
57 
58 //释放内存
59     for(i = 0;i<lineCount;i++)
60     {
61         for(j = 0;j<7;j++)//这儿给定死了
62         {
63             free( *(*(storage+i)+j));
64         }
65         if(i != lineCount-1)//为了照顾最后一行,竟然如此麻烦, 还是写个先去除无用信息的版本代码为好。
66             free(*(*(storage+i)+j));
67         free(*(storage+i));
68     }
69 
70     return 0;
71 }



版本3: 待补








原文地址:https://www.cnblogs.com/ZhuLuoJiGongYuan/p/9556023.html