strtok()函数、fseek()函数、fwrite()函数、fread()函数的使用
在电子词典这个项目过程中遇到了几个主要的问题,第一个是怎么解决把翻译分开这个。第二个事情就是怎么把结构体写到文件中。这两个问题,一个是关于字符串的操作一个是关于文件的操作。
strtok函数 char *strtok(char *string, char *seps)
函数功能:将字符串string中所有在seps中出现的分隔符替换掉。
返回说明:返回指向下一个标记串,当没有标记串时则返回空字符NULL。
其它说明: 当第一次调用strtok函数的时候,strtok函数跳过seps中的第一个分隔符,同时返回在string中的出现的第一个分隔符的位置的指针,用一个空字符'/0'终止。通过循环,经过多次调用strtok函数,seps中更多的分隔字符都会被'/0'替换掉,最终输出我们意图实现的字符串。
实例:
for((token = strtok(buf, “@”)); token != NULL; token = strtok(NULL, “@”)) { {
k++; strcpy(buffer[k], token); }
如果字符串buf中含有很多“@”分隔符,上边这个循环第一次将buf字符串的头到第一个“@”之间的字符串返回给token,可以将token赋值给buffer[k],第二次就是从第一“@”到第二个“@”之间的字符串返回给token,以此类推将整个buf中的所有数据根据分隔符“@”分开了。
第二个问题是关于文件的操作,怎么样把结构体写到文件中,怎么样定你写的结构体在文件中的读写位置。
读写结构体其实也比较简单,结构体在定义的时候,所占的内存已经确定,因此直接写进去就会按照结构体中的顺序和所占的字节数就能够直接写,但是需要注意的是,读的时候一定要写的时候格式一样,这样才能不出错。如下面的读写函数。
fwrite.c
#include <stdio.h> #define SIZE 2 struct word { char word[10]; int trans_num; char trans[10]; }Word[SIZE]; void save() { FILE *fp; int i; if((fp=fopen("word.dat","wb"))==NULL) { printf("cant open the file"); exit(0); } for(i=0;i<SIZE;i++) { if(fwrite(&Word[i],sizeof(struct word),1,fp)!=1) printf("file write error\n"); } fclose(fp); } main() { int i; for(i=0;i<SIZE;i++) { scanf("%s%d%s",&Word[i].word,&Word[i].trans_num,&Word[i].trans); save(); } for(i=0;i<SIZE;i++) { printf("%s%d%s",&Word[i].word,&Word[i].trans_num,&Word[i].trans); } }
fread.c
#include <stdio.h> #define SIZE 2 struct word { char word[10]; int trans_num; char trans[10]; }Word[SIZE]; void read() { FILE *fp; int i; if((fp=fopen("word.dat","rb"))==NULL) { printf("cant open the file"); exit(0); } for(i=0;i<SIZE;i++) { if(fread(&Word[i],sizeof(struct word),1,fp)!=1) printf("file write error\n"); } fclose(fp); } main() { int i; read(); for(i=0;i<SIZE;i++) { printf("%s%d%s",&Word[i].word,&Word[i].trans_num,&Word[i].trans); printf("\n"); } }
上边两个程序就是结构体的读写函数,上边程序你可以在运行的时候计算一下一个结构体的字节数,你会发现都是一样的大小,因此如果你要想要直接从dat文件中读出结构体数组中的第二个元素,你就可以fseek函数定位到第二个元素的其实位置直接读就可以了。
int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
对于上边的代码来说,如果想要读出第二个元素就可以在fread函数前加 fseek(FILE *fp, sizeof(struct word), SEEK_SET); 这样就是从第二个元素开始读,如果有一个更大的文件还是以这个格式写进去的话,可以通过 fseek(FILE *fp,n* sizeof(struct word), SEEK_SET); 来直接读出第n个结点的值。