user-0 提问: 萌新求助

回复:
user: user-1
content: 引用 13 楼 amotym 的回复:[quote=引用 10 楼 拥抱Linux的回复:]既然没有报错，说明程序肯定是完全运行下去了的。 嗯，没有输出的话，看看在你的电脑上，实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢，还是没有想要的内容呢？ 找到原因了，我的info前面有一个tab的位置[/quote] 哦，原来如此，程序一直没有找到一模一样的字符串"<info>"。昨天晚上尝试写代码的时候，都是顺手写下去的，对于这类读入异常的情况没有做什么识别、判断，毕竟太费事了。你如有有实际需要的话，可以自己尝试添加相关的检测代码哦。 好了，总之能得到想要的结果就好。 ～

user: user-1
content: 引用 11 楼 amotym 的回复: 看样子是进入死循环了，俺估计是在 fscanf 和 fgetc 的地方进入死循环的，因为文件指针没有走到下一行。 试试把所有的 fget 替换为 fgets 函数，如下：          // 在main 函数的开头，定义一个字符数组，用来接收所读取文件的每行的末尾残余字符         char empty[100]; 	         //fgetc(fp);         fgets(empty,10,fp);  俺这边运行下来，结果是一样的，都可以输出。你再试试。 还不行的话，可以把你实际的代码，和你实际的 xml 文件内容都放上来，俺复制过来再实际运行试试。 ～ 另外，不知道你的是纯Ubuntu还是windows下的WSL，究竟对于读取文本文件有没有影响俺不是太清楚，不过windows的换行符和linux的换行符不一样，有可能导致上面的代码下，文件指针没有前往下一行。

user: user-0
content: 引用 10 楼 拥抱Linux的回复:既然没有报错，说明程序肯定是完全运行下去了的。 嗯，没有输出的话，看看在你的电脑上，实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢，还是没有想要的内容呢？ 找到原因了，我的info前面有一个tab的位置

user: user-0
content: 引用 10 楼 拥抱Linux的回复:既然没有报错，说明程序肯定是完全运行下去了的。 嗯，没有输出的话，看看在你的电脑上，实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢，还是没有想要的内容呢？ 用的是一模一样的例子

user: user-0
content: 引用 9 楼 拥抱Linux 的回复:[quote=引用 8 楼 amotym 的回复:] 谢谢啦，Ubuntu16.04中无输出 俺的系统是elementary Loki，同样是基于Ubuntu 16.04的，程序运行结果就是上面的截图那样啊。 录了一张gif动图，不知道csdn论坛支不支持，发一下试试。 [/quote]

user: user-1
content: 既然没有报错，说明程序肯定是完全运行下去了的。 嗯，没有输出的话，看看在你的电脑上，实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢，还是没有想要的内容呢？

user: user-1
content: 引用 8 楼 amotym 的回复:谢谢啦，Ubuntu16.04中无输出 俺的系统是elementary Loki，同样是基于Ubuntu 16.04的，程序运行结果就是上面的截图那样啊。 录了一张gif动图，不知道csdn论坛支不支持，发一下试试。

user: user-0
content: 引用 7 楼 拥抱Linux的回复:[quote=引用 6 楼 amotym 的回复:] 可不可以请教一下从info的下一行开始存储 动态申请内存吧。 在Linux环境下写了一下代码，不够优雅，仅供参考。 具体而言，是根据你提供的测试文本test.xml来写的，没有考虑其它比如文本内容有异常的情况哦。 另外，Windows环境下没有测试过，有问题的话自己调试吧，俺爱莫能助。  #include <stdio.h> #include <stdlib.h> #include <string.h>  int main(int argc, char const *argv[]) { 	FILE *fp; 	fp = fopen("test.xml", "r"); 	if (NULL == fp) { 		printf("Error! File open #1 failed!\n"); 		exit(EXIT_FAILURE); 	}  	/*遍历test.xml，得到所需数据的行数，即字符数组数*/ 	char info_start[10] = "<info>"; 	char info_end[10] = "</info>"; 	char line_check[1000];  	// 按行来读取，需要额外添加一行来读取行尾换行符 	fscanf(fp, "%[^\n]", line_check); 	fgetc(fp);  	while (0 != strcmp(info_start, line_check) && !feof(fp)) { 		fscanf(fp, "%[^\n]", line_check); 		fgetc(fp); 	} 	int parenthesis_count = 0; 	fscanf(fp, "%[^\n]", line_check); 	fgetc(fp); 	while (0 != strcmp(info_end, line_check)) { 		char *p = line_check; 		while ('\0' != *p) { 			if ('(' == *p) { 				while (')' != *p && '\0' != *p) { 					p++; 				} 				if (')' == *p) { 					parenthesis_count++; 				} else if ('\0' == *p) { 					printf("Warning : missing ')' !"); 				} 			} else { 				p++; 			} 		} 		fscanf(fp, "%[^\n]", line_check); 		fgetc(fp); 	} 	fclose(fp);  	// 开始获取需要的字符串  	fp = fopen("test.xml", "r"); 	if (NULL == fp) { 		printf("Error! File open #2 failed!\n"); 		exit(EXIT_FAILURE); 	}  	// 指针数组，存储各个字符数组的首地址 	char *whole[parenthesis_count]; 	int count = 0;  	char search[1000]; 	fscanf(fp, "%[^\n]", search); 	fgetc(fp); 	while (0 != strcmp(info_start, search)) { 		fscanf(fp, "%[^\n]", search); 		fgetc(fp); 	}  	fscanf(fp, "%[^\n]", search); 	fgetc(fp); 	while (0 != strcmp(info_end, search)) { 		char *p = search; 		char *q = search; 		while ('\0' != *p) { 			p = strchr(p, '(') + 1; 			q = p; 			p = strchr(p, ')') + 1; 			int len = p - q - 1; 			char *dst = (char *)malloc(sizeof(char) * (len + 1)); 			for (int i = 0; i < len; i++) { 				dst[i] = *q; 				q++; 			} 			dst[len] = '\0'; 			whole[count++] = dst; 		} 		fscanf(fp, "%[^\n]", search); 		fgetc(fp); 	}  	fclose(fp);  	for (int i = 0; i < count; i++) { 		printf("%s\n", whole[i]); 	}  	for (int i = 0; i < count; i++) { 		free(whole[i]); 		whole[i] = NULL; 	}  	return 0; }  Linux环境，运行截图： （1）局部，  （2）局部，  如有帮助，欢迎 及时 结帖、给分！：-） ～[/quote] 谢谢啦，Ubuntu16.04中无输出😂

user: user-1
content: 引用 6 楼 amotym 的回复:可不可以请教一下从info的下一行开始存储 动态申请内存吧。 在Linux环境下写了一下代码，不够优雅，仅供参考。 具体而言，是根据你提供的测试文本test.xml来写的，没有考虑其它比如文本内容有异常的情况哦。 另外，Windows环境下没有测试过，有问题的话自己调试吧，俺爱莫能助。  #include <stdio.h> #include <stdlib.h> #include <string.h>  int main(int argc, char const *argv[]) { 	FILE *fp; 	fp = fopen("test.xml", "r"); 	if (NULL == fp) { 		printf("Error! File open #1 failed!\n"); 		exit(EXIT_FAILURE); 	}  	/*遍历test.xml，得到所需数据的行数，即字符数组数*/ 	char info_start[10] = "<info>"; 	char info_end[10] = "</info>"; 	char line_check[1000];  	// 按行来读取，需要额外添加一行来读取行尾换行符 	fscanf(fp, "%[^\n]", line_check); 	fgetc(fp);  	while (0 != strcmp(info_start, line_check) && !feof(fp)) { 		fscanf(fp, "%[^\n]", line_check); 		fgetc(fp); 	} 	int parenthesis_count = 0; 	fscanf(fp, "%[^\n]", line_check); 	fgetc(fp); 	while (0 != strcmp(info_end, line_check)) { 		char *p = line_check; 		while ('\0' != *p) { 			if ('(' == *p) { 				while (')' != *p && '\0' != *p) { 					p++; 				} 				if (')' == *p) { 					parenthesis_count++; 				} else if ('\0' == *p) { 					printf("Warning : missing ')' !"); 				} 			} else { 				p++; 			} 		} 		fscanf(fp, "%[^\n]", line_check); 		fgetc(fp); 	} 	fclose(fp);  	// 开始获取需要的字符串  	fp = fopen("test.xml", "r"); 	if (NULL == fp) { 		printf("Error! File open #2 failed!\n"); 		exit(EXIT_FAILURE); 	}  	// 指针数组，存储各个字符数组的首地址 	char *whole[parenthesis_count]; 	int count = 0;  	char search[1000]; 	fscanf(fp, "%[^\n]", search); 	fgetc(fp); 	while (0 != strcmp(info_start, search)) { 		fscanf(fp, "%[^\n]", search); 		fgetc(fp); 	}  	fscanf(fp, "%[^\n]", search); 	fgetc(fp); 	while (0 != strcmp(info_end, search)) { 		char *p = search; 		char *q = search; 		while ('\0' != *p) { 			p = strchr(p, '(') + 1; 			q = p; 			p = strchr(p, ')') + 1; 			int len = p - q - 1; 			char *dst = (char *)malloc(sizeof(char) * (len + 1)); 			for (int i = 0; i < len; i++) { 				dst[i] = *q; 				q++; 			} 			dst[len] = '\0'; 			whole[count++] = dst; 		} 		fscanf(fp, "%[^\n]", search); 		fgetc(fp); 	}  	fclose(fp);  	for (int i = 0; i < count; i++) { 		printf("%s\n", whole[i]); 	}  	for (int i = 0; i < count; i++) { 		free(whole[i]); 		whole[i] = NULL; 	}  	return 0; }  Linux环境，运行截图： （1）局部，  （2）局部，  如有帮助，欢迎 及时 结帖、给分！：-） ～

user: user-0
content: 引用 3 楼 拥抱Linux的回复:（1）打开文件，（2）按行比较字符串，找到<info>，（3）从下一行开始读取数据，并存入字符数组，一对圆括号表示一个数组，（4）按行比较到</info>则结束读取。（5）关闭文件指针。  设置可以查找的指针。  是什么意思？ 用一个函数来传入字符指针，在前面获得的字符数组集合里查询有无相应的字符串，并且返回字符串的位置么？ ～ 可不可以请教一下从info的下一行开始存储

user: user-0
content: 引用 4 楼 amotym的回复:[quote=引用 3 楼 拥抱Linux的回复:]（1）打开文件，（2）按行比较字符串，找到<info>，（3）从下一行开始读取数据，并存入字符数组，一对圆括号表示一个数组，（4）按行比较到</info>则结束读取。（5）关闭文件指针。  设置可以查找的指针。  是什么意思？ 用一个函数来传入字符指针，在前面获得的字符数组集合里查询有无相应的字符串，并且返回字符串的位置么？ ～ 是的，就是这个意思。[/quote] 可不可以请教一下从info的下一行开始存储

user: user-0
content: 引用 3 楼 拥抱Linux的回复:（1）打开文件，（2）按行比较字符串，找到<info>，（3）从下一行开始读取数据，并存入字符数组，一对圆括号表示一个数组，（4）按行比较到</info>则结束读取。（5）关闭文件指针。  设置可以查找的指针。  是什么意思？ 用一个函数来传入字符指针，在前面获得的字符数组集合里查询有无相应的字符串，并且返回字符串的位置么？ ～ 是的，就是这个意思。

user: user-1
content: （1）打开文件，（2）按行比较字符串，找到<info>，（3）从下一行开始读取数据，并存入字符数组，一对圆括号表示一个数组，（4）按行比较到</info>则结束读取。（5）关闭文件指针。  设置可以查找的指针。  是什么意思？ 用一个函数来传入字符指针，在前面获得的字符数组集合里查询有无相应的字符串，并且返回字符串的位置么？ ～

user: user-0
content: 引用 1 楼 赵4老师的回复:仅供参考：//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-2
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