user-0 提问: 【新手求教~！】还是关于文本读取的问题~~

回复:
user: user-1
content: 仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

user: user-0
content: 引用 9 楼 hongwenjun 的回复:#include <stdio.h> #include <string.h>  int main() {     FILE* pFile;     char* pch;     char str [255] = {0};      pFile = fopen("tel.csv" , "r");     if (pFile == NULL) {         perror("Error opening file");         return -1;     }     fgets(str , 255 , pFile);     while (! feof(pFile)) {         pch = strtok(str, ",\n");         while (pch != NULL) {             printf("%s\t", pch);             pch = strtok(NULL, ",\n");         }         printf("\n");         fgets(str , 255 , pFile);  // 这样写法 解决BUG，不会输出最后一行的名字      }     fclose(pFile);     return 0; } /* 输出结果 姓名    办电    宅电    手机    虚拟网 卢小珍  34521111        88903453        13537902123     332123 童云龙  34521113        88927528        13503793985     373985 童万贞  34521112        34523377        13803778530     338530  */   数据文件 tel.csv 姓名,办电,宅电,手机,虚拟网 卢小珍,34521111,88903453,13537902123,332123 童云龙,34521113,88927528,13503793985,373985 童万贞,34521112,34523377,13803778530,338530 卢小珍,34521111,88903453,13537902123,332123 这个没看明白哦，姓名得是一个字段里面的，分别读取其中的卢小珍，童云龙，读姓名时不用读出来办电和手机的。。。这个是直接读取全部的内容咯

user: user-0
content: 引用 8 楼 zjq9931 的回复:[quote=引用 7 楼 aabcg129 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   } [/quote]  fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针，指针+1就是字段的内容。 结合一些字符串操作函数，就可以取出每个字段。[/quote] fgetc换成fgets 编译就报错了[Error] cannot convert 'FILE* {aka _iobuf*}' to 'char*' for argument '1' to 'char* fgets(char*, int, FILE*)' 然后各个字段怎么就能实现分开读取的情况，还请指教~有代码最好理解了

user: user-2
content: 引用 4 楼 aabcg129 的回复:[quote=引用 1 楼 u011648839 的回复:] 不能用数组就用char*直接写死啊，就不能修改了 读的时候就一个字符一个字符比较呗，每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了  主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了[/quote] 不能用数组的是没办法的 任何信息只要是连续的有序的同类的，都可以看做数组，并不是非得char a[10]才叫数组 只要你在内存里把张三这两个字排列出来，我就可以说这是一个数组

user: user-3
content: #include <stdio.h> #include <string.h>  int main() {     FILE* pFile;     char* pch;     char str [255] = {0};      pFile = fopen("tel.csv" , "r");     if (pFile == NULL) {         perror("Error opening file");         return -1;     }     fgets(str , 255 , pFile);     while (! feof(pFile)) {         pch = strtok(str, ",\n");         while (pch != NULL) {             printf("%s\t", pch);             pch = strtok(NULL, ",\n");         }         printf("\n");         fgets(str , 255 , pFile);  // 这样写法 解决BUG，不会输出最后一行的名字      }     fclose(pFile);     return 0; } /* 输出结果 姓名    办电    宅电    手机    虚拟网 卢小珍  34521111        88903453        13537902123     332123 童云龙  34521113        88927528        13503793985     373985 童万贞  34521112        34523377        13803778530     338530  */   数据文件 tel.csv 姓名,办电,宅电,手机,虚拟网 卢小珍,34521111,88903453,13537902123,332123 童云龙,34521113,88927528,13503793985,373985 童万贞,34521112,34523377,13803778530,338530 卢小珍,34521111,88903453,13537902123,332123

user: user-4
content: 引用 7 楼 aabcg129 的回复:[quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   } [/quote]  fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针，指针+1就是字段的内容。 结合一些字符串操作函数，就可以取出每个字段。

user: user-0
content: 引用 5 楼 zjq9931 的回复:[quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   }

user: user-0
content: 引用 3 楼 cfjtaishan 的回复:这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写

user: user-4
content: 引用 4 楼 aabcg129 的回复:主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。

user: user-0
content: 引用 1 楼 u011648839 的回复:不能用数组就用char*直接写死啊，就不能修改了 读的时候就一个字符一个字符比较呗，每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了  主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了

user: user-5
content: 这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。

user: user-6
content: 平台关系很大啊，如果有类似于getline这样的函数，就一行一行读，然后套用相同的规则去解析出各字段。 当然如果没有也没关系，读到\n就是一行嘛

user: user-2
content: 不能用数组就用char*直接写死啊，就不能修改了 读的时候就一个字符一个字符比较呗，每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了

user: user-0
content: 引用 20 楼 zhao4zhong1 的回复:[quote=引用 19 楼 hzy_76 的回复:] 上面有朋友给出fsanf的方法，应该可行，不过format中的\n应该不要，即这样写：  fscanf("%s %d %s %s %s", name, &age, sex, tel, address);  你必须把所有列都一次性读出来，只是某些列不用来显示罢了，此时文件指针会自动往后移。 无意义并且无规则的行，可以用读行的函数读出来后不处理，使文件指针后移。 不要的列可以在%后面加*跳过。[/quote]受教了！

user: user-6
content: 受教了，谢谢！

user: user-1
content: 引用 19 楼 hzy_76 的回复:上面有朋友给出fsanf的方法，应该可行，不过format中的\n应该不要，即这样写：  fscanf("%s %d %s %s %s", name, &age, sex, tel, address);  你必须把所有列都一次性读出来，只是某些列不用来显示罢了，此时文件指针会自动往后移。 无意义并且无规则的行，可以用读行的函数读出来后不处理，使文件指针后移。 不要的列可以在%后面加*跳过。

user: user-6
content: 上面有朋友给出fsanf的方法，应该可行，不过format中的\n应该不要，即这样写：  fscanf("%s %d %s %s %s", name, &age, sex, tel, address);  你必须把所有列都一次性读出来，只是某些列不用来显示罢了，此时文件指针会自动往后移。 无意义并且无规则的行，可以用读行的函数读出来后不处理，使文件指针后移。

user: user-0
content: //#include <stdio.h> #include <stdlib.h> #include <memory.h> int main(void) { FILE *fp = NULL; char buf[1024] = {0}; int count = 0; int row = 0; int ch = 0; fp = fopen("host.txt", "r"); if (fp == NULL) { printf("Cann't open the file!\n"); exit(1); } else { while (1) { printf("Input a row you want to read: \n"); scanf("%d", &row);  fflush(stdin); while (!feof(fp)) { fgets(buf, 1024, fp); count++; if (row == count) { printf("%s", buf); } memset(buf, 0, sizeof(buf)); } count = 0; rewind(fp); printf("go on? [y/n]: "); scanf("%c", &ch); fflush(stdin); if (ch == 'y' || ch == 'Y') { continue; } else { break; } } fclose(fp); } return 0; } 刚在网上看到或者读任意一行的代码~但还是不知道如何把name字段下的东西放进一个组里~啊啊啊啊啊~哪位大神能写个代码啊啊啊啊~抓狂ing ~img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/50.gif][/img]

user: user-0
content: 引用 16 楼 cfjtaishan 的回复:[quote=引用 6 楼 aabcg129 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里，这个数据建议用malloc/realloc申请空间，因为读文件不知道文件有多少个人的信息； 用户输入age时，你就循环遍历数组，一个个比较，若相等直接输出下表即可。因为数组下表就是在文件内的第几行（数组下表是从0开始）[/quote] 太高深了~实在不明白~不过还是谢谢您~

user: user-5
content: 引用 6 楼 aabcg129 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里，这个数据建议用malloc/realloc申请空间，因为读文件不知道文件有多少个人的信息； 用户输入age时，你就循环遍历数组，一个个比较，若相等直接输出下表即可。因为数组下表就是在文件内的第几行（数组下表是从0开始）