user-0 提问: 读取文件数据

回复:
user: user-1
content: 现在都把“脾气暴躁”的名人称作“有个性”！

user: user-0
content: 引用 4 楼 user-2 的回复:我根据自己的理解做了一下，不知跟楼主需要的是否一致：  #include <stdio.h> #include <string.h> #include <stdlib.h>  #define TTLSIZE		81  //读入文件中每个字符串的总长限定 #define	STRSIZE		61  //读入#等字符之后的字符串的长度限定 #define MAX			21  //读入!之后的中文字符串的长度限定 #define NUM			 3  //文件中字符串的数目  struct strings { 	char head;         //装载! 	char name[MAX];    //装载!之后的中文字符串 	char contrlch;     //装载名字之后的那个字符#, $以及* 	char str[STRSIZE]; //装载#等字符之后的字符串 };                     //用结构体装载字符串的不同部分  int main(void) { 	struct strings strs[NUM]; 	int i = 0; 	char * pstring, * pname, * pstr; 	char string[NUM][TTLSIZE]; //用以整个读取文件中的3个字符串 	char ctrlch[NUM] = {'#', '$', '*'}; 	FILE * fp;  	if((fp = fopen("data.txt", "r")) == NULL) 	{ 		fputs( "Error reading file.", stderr); 		exit(EXIT_FAILURE); 	} 	while(i < NUM && fgets(string[i], TTLSIZE, fp) != NULL && string[i][0] != '\n')         i++;        //整个读取文件中的字符串 	for(i = 0; i < NUM; i++) 	{ 		pstring = string[i];    //用以扫描string[i]中的字符 		pname = strs[i].name;   //用以读入！之后的中文字符串 		pstr = strs[i].str;     //用以读如#等之后的字符串 		while(* pstring) 		{ 			if(* pstring == '!')             {                 strs[i].head = *pstring; //遇到的第一个字符!，就读入到str[i].head中                 pstring++;               //将指针往下移动一个，以便后续操作读取!之后             }                            //的中文字符串             else if(*pstring == ctrlch[i])  //             {                 strs[i].contrlch = * pstring;  //将#等字符读入到str[i].contrlch中                 pstring++;    //指针往下移动一个，以便从#等字符之后开始接着读取其他字符                 while(* pstring)  //接着读取#等字符之后的其他字符                     * pstr++ = * pstring++;                 * pstr = '\0';             //读取完毕，加上一个空字符形成字符串             } 			else 			{ 				while(*pstring != ctrlch[i])                     *pname++ = *pstring++;   //读取!之后的中文字符串 				*pname = '\0'; 			} 		} 	}  	puts("Output:"); 	for(i = 0; i < NUM; i++) 		printf("%c%s%c%s", strs[i].head, strs[i].name, strs[i].contrlch, strs[i].str);  	return 0; }   是这个意思，我用你的跑了下。也能达到效果。。不过还是老师的那个全面些。

user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 a13728843352 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  //in.txt //!矩阵#fe 00 01 01 01 00 01 ff //!高速球$ff 01 00 20 00 00 21 //!画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae #include <stdio.h> char ln[600]; char nm[30]; FILE *f; char b[200]; char *p,c; int i,r,n,v,L; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     L=0;     while (1) {         if (NULL==fgets(ln,600,f)) break;         L++;         r=sscanf(ln,"!%29[^#$*]%c%n",nm,&c,&n);         if (2==r && ('#'==c || '$'==c || '*'==c)) {             p=ln+n;             i=0;             while (1) {                 r=sscanf(p,"%2x%n",&v,&n);                 if (1==r) {                     b[i]=(char)v;                     i++;                     if (i>=200) break;                     p+=n;                 } else if (0==r) {p++;} else break;             }             printf("%s%c",nm,c);             n=i;             for (i=0;i<n;i++) printf("%02x ",(unsigned char)b[i]);             printf("\n");             continue;         }         printf("Line %d Format Error:%s",L,ln);     }     fclose(f);     return 0; } //矩阵#fe 00 01 01 01 00 01 ff //高速球$ff 01 00 20 00 00 21 //画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae //   嘿嘿。。在发问题的时候。我是自己做到了。 我的代码是这样的  		for (int i = 0; i < 128 ; i++) 		{ 			_cprintf("begin to read\n");  			fseek(fp,i,SEEK_SET);  			//fread(buf,1,1,fp);//每次从文件读取一 			fgets(&nameBuf[i],2,fp);  			if (nameBuf[0] != '!') 			{ 				_cprintf("the head is wrong!\n"); 				return; 			}  			if ((nameBuf[i] == '#')||(nameBuf[i] == '$')||(nameBuf[i] == '@')||(nameBuf[i] == '*')) 			{ 				//找到尾巴了 				fseek(fp,1,SEEK_SET);  				memset(&nameBuf,0,256);  				fgets(nameBuf,i,fp);//长度是从1到i+1，去掉头尾，就是i-1 				_cprintf("the name buf is %s \n",nameBuf);//矩阵  				fseek(fp,i+1,SEEK_SET); 				fgets(cmdBuf,128,fp); 				_cprintf("the cmd buf is %s \n",cmdBuf);// fe 00 01 01 01 00 01 ff  				i = 128; 			} 		}   可是接下来我怎么决定去换行，读取第二行呢[/quote] 把你自己的代码打印到一张纸上，然后团吧团吧扔进垃圾桶！  把我的代码也打印到一张纸上，两倍行间距，逐字逐句单步调试对照弄懂每句、每个词、每个字母的功能，必要的用铅笔标注在纸上对应地方。完成后弄个贵点的土豪金相框，挂枕头边上。每天对其默背三遍！ [/quote]  哈哈，老师别生气。回了一趟家。现在我看懂了。。

user: user-2
content: 我根据自己的理解做了一下，不知跟楼主需要的是否一致：  #include <stdio.h> #include <string.h> #include <stdlib.h>  #define TTLSIZE		81  //读入文件中每个字符串的总长限定 #define	STRSIZE		61  //读入#等字符之后的字符串的长度限定 #define MAX			21  //读入!之后的中文字符串的长度限定 #define NUM			 3  //文件中字符串的数目  struct strings { 	char head;         //装载! 	char name[MAX];    //装载!之后的中文字符串 	char contrlch;     //装载名字之后的那个字符#, $以及* 	char str[STRSIZE]; //装载#等字符之后的字符串 };                     //用结构体装载字符串的不同部分  int main(void) { 	struct strings strs[NUM]; 	int i = 0; 	char * pstring, * pname, * pstr; 	char string[NUM][TTLSIZE]; //用以整个读取文件中的3个字符串 	char ctrlch[NUM] = {'#', '$', '*'}; 	FILE * fp;  	if((fp = fopen("data.txt", "r")) == NULL) 	{ 		fputs( "Error reading file.", stderr); 		exit(EXIT_FAILURE); 	} 	while(i < NUM && fgets(string[i], TTLSIZE, fp) != NULL && string[i][0] != '\n')         i++;        //整个读取文件中的字符串 	for(i = 0; i < NUM; i++) 	{ 		pstring = string[i];    //用以扫描string[i]中的字符 		pname = strs[i].name;   //用以读入！之后的中文字符串 		pstr = strs[i].str;     //用以读如#等之后的字符串 		while(* pstring) 		{ 			if(* pstring == '!')             {                 strs[i].head = *pstring; //遇到的第一个字符!，就读入到str[i].head中                 pstring++;               //将指针往下移动一个，以便后续操作读取!之后             }                            //的中文字符串             else if(*pstring == ctrlch[i])  //             {                 strs[i].contrlch = * pstring;  //将#等字符读入到str[i].contrlch中                 pstring++;    //指针往下移动一个，以便从#等字符之后开始接着读取其他字符                 while(* pstring)  //接着读取#等字符之后的其他字符                     * pstr++ = * pstring++;                 * pstr = '\0';             //读取完毕，加上一个空字符形成字符串             } 			else 			{ 				while(*pstring != ctrlch[i])                     *pname++ = *pstring++;   //读取!之后的中文字符串 				*pname = '\0'; 			} 		} 	}  	puts("Output:"); 	for(i = 0; i < NUM; i++) 		printf("%c%s%c%s", strs[i].head, strs[i].name, strs[i].contrlch, strs[i].str);  	return 0; }

user: user-1
content: 引用 2 楼 a13728843352 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  //in.txt //!矩阵#fe 00 01 01 01 00 01 ff //!高速球$ff 01 00 20 00 00 21 //!画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae #include <stdio.h> char ln[600]; char nm[30]; FILE *f; char b[200]; char *p,c; int i,r,n,v,L; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     L=0;     while (1) {         if (NULL==fgets(ln,600,f)) break;         L++;         r=sscanf(ln,"!%29[^#$*]%c%n",nm,&c,&n);         if (2==r && ('#'==c || '$'==c || '*'==c)) {             p=ln+n;             i=0;             while (1) {                 r=sscanf(p,"%2x%n",&v,&n);                 if (1==r) {                     b[i]=(char)v;                     i++;                     if (i>=200) break;                     p+=n;                 } else if (0==r) {p++;} else break;             }             printf("%s%c",nm,c);             n=i;             for (i=0;i<n;i++) printf("%02x ",(unsigned char)b[i]);             printf("\n");             continue;         }         printf("Line %d Format Error:%s",L,ln);     }     fclose(f);     return 0; } //矩阵#fe 00 01 01 01 00 01 ff //高速球$ff 01 00 20 00 00 21 //画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae //   嘿嘿。。在发问题的时候。我是自己做到了。 我的代码是这样的  		for (int i = 0; i < 128 ; i++) 		{ 			_cprintf("begin to read\n");  			fseek(fp,i,SEEK_SET);  			//fread(buf,1,1,fp);//每次从文件读取一 			fgets(&nameBuf[i],2,fp);  			if (nameBuf[0] != '!') 			{ 				_cprintf("the head is wrong!\n"); 				return; 			}  			if ((nameBuf[i] == '#')||(nameBuf[i] == '$')||(nameBuf[i] == '@')||(nameBuf[i] == '*')) 			{ 				//找到尾巴了 				fseek(fp,1,SEEK_SET);  				memset(&nameBuf,0,256);  				fgets(nameBuf,i,fp);//长度是从1到i+1，去掉头尾，就是i-1 				_cprintf("the name buf is %s \n",nameBuf);//矩阵  				fseek(fp,i+1,SEEK_SET); 				fgets(cmdBuf,128,fp); 				_cprintf("the cmd buf is %s \n",cmdBuf);// fe 00 01 01 01 00 01 ff  				i = 128; 			} 		}   可是接下来我怎么决定去换行，读取第二行呢[/quote] 把你自己的代码打印到一张纸上，然后团吧团吧扔进垃圾桶！  把我的代码也打印到一张纸上，两倍行间距，逐字逐句单步调试对照弄懂每句、每个词、每个字母的功能，必要的用铅笔标注在纸上对应地方。完成后弄个贵点的土豪金相框，挂枕头边上。每天对其默背三遍！

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  //in.txt //!矩阵#fe 00 01 01 01 00 01 ff //!高速球$ff 01 00 20 00 00 21 //!画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae #include <stdio.h> char ln[600]; char nm[30]; FILE *f; char b[200]; char *p,c; int i,r,n,v,L; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     L=0;     while (1) {         if (NULL==fgets(ln,600,f)) break;         L++;         r=sscanf(ln,"!%29[^#$*]%c%n",nm,&c,&n);         if (2==r && ('#'==c || '$'==c || '*'==c)) {             p=ln+n;             i=0;             while (1) {                 r=sscanf(p,"%2x%n",&v,&n);                 if (1==r) {                     b[i]=(char)v;                     i++;                     if (i>=200) break;                     p+=n;                 } else if (0==r) {p++;} else break;             }             printf("%s%c",nm,c);             n=i;             for (i=0;i<n;i++) printf("%02x ",(unsigned char)b[i]);             printf("\n");             continue;         }         printf("Line %d Format Error:%s",L,ln);     }     fclose(f);     return 0; } //矩阵#fe 00 01 01 01 00 01 ff //高速球$ff 01 00 20 00 00 21 //画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae //   嘿嘿。。在发问题的时候。我是自己做到了。 我的代码是这样的  		for (int i = 0; i < 128 ; i++) 		{ 			_cprintf("begin to read\n");  			fseek(fp,i,SEEK_SET);  			//fread(buf,1,1,fp);//每次从文件读取一 			fgets(&nameBuf[i],2,fp);  			if (nameBuf[0] != '!') 			{ 				_cprintf("the head is wrong!\n"); 				return; 			}  			if ((nameBuf[i] == '#')||(nameBuf[i] == '$')||(nameBuf[i] == '@')||(nameBuf[i] == '*')) 			{ 				//找到尾巴了 				fseek(fp,1,SEEK_SET);  				memset(&nameBuf,0,256);  				fgets(nameBuf,i,fp);//长度是从1到i+1，去掉头尾，就是i-1 				_cprintf("the name buf is %s \n",nameBuf);//矩阵  				fseek(fp,i+1,SEEK_SET); 				fgets(cmdBuf,128,fp); 				_cprintf("the cmd buf is %s \n",cmdBuf);// fe 00 01 01 01 00 01 ff  				i = 128; 			} 		}   可是接下来我怎么决定去换行，读取第二行呢

user: user-1
content: 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  //in.txt //!矩阵#fe 00 01 01 01 00 01 ff //!高速球$ff 01 00 20 00 00 21 //!画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae #include <stdio.h> char ln[600]; char nm[30]; FILE *f; char b[200]; char *p,c; int i,r,n,v,L; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     L=0;     while (1) {         if (NULL==fgets(ln,600,f)) break;         L++;         r=sscanf(ln,"!%29[^#$*]%c%n",nm,&c,&n);         if (2==r && ('#'==c || '$'==c || '*'==c)) {             p=ln+n;             i=0;             while (1) {                 r=sscanf(p,"%2x%n",&v,&n);                 if (1==r) {                     b[i]=(char)v;                     i++;                     if (i>=200) break;                     p+=n;                 } else if (0==r) {p++;} else break;             }             printf("%s%c",nm,c);             n=i;             for (i=0;i<n;i++) printf("%02x ",(unsigned char)b[i]);             printf("\n");             continue;         }         printf("Line %d Format Error:%s",L,ln);     }     fclose(f);     return 0; } //矩阵#fe 00 01 01 01 00 01 ff //高速球$ff 01 00 20 00 00 21 //画面分割器*a5 6c 15 00 81 00 01 00 00 00 00 00 00 00 00 00 18 01 c1 01 ae //