一、案例完整代码
点击(此处)折叠或打开
-
/****************************************************************
-
* Name : sort_and_output.c
-
* Author : dyli2000
-
* Date : 20121102
-
* Description :
- 对学生成绩由高到低输出案例。扩展功能:
- 随机产生学生成绩,并写入到fin.txt;然后读fin.txt中的数据,排序输出到out.txt
- 文件。
-
****************************************************************/
- #include stdio.h>
- #include time.h>
- #include string.h>
- #define DEBUG
- #define TIMES 20
- typedef struct StringNode
-
{
- char str[100];
- int num;
-
}str_node;
-
/* Must put it here !! */
- str_node str_node_array[TIMES];
-
int fsort(char* fin,char* fout)
-
{
- #ifdef DEBUG
- printf("Before sort the string:\n%s\n",fin);
- #endif
- //str_node str_node_array[TIMES]; // Error usage
- memset(str_node_array,0,TIMES);
- int in = 0;
- char *p[TIMES];
- char *buf = fin;
- char *p_num = NULL;
- char *outer_ptr = NULL;
- char *inner_ptr = NULL;
- #ifdef DEBUG
- printf("---------------------1111111111111111111111111111111111 buf:\n%s\n",buf);
- #endif
- while((p[in] = strtok_r(buf,"\n",&outer_ptr)) != NULL && in TIMES)
- {
- buf = p[in];
- strcpy(str_node_array[in].str,buf);
- if( (strtok_r(buf," ",&inner_ptr) ) != NULL )
- {
- if( (p_num = strtok_r(NULL," ",&inner_ptr) ) != NULL)
- {
- str_node_array[in].num = atoi(p_num);
- #ifdef DEBUG
- printf("str_node_array[%d].str:%s\n",in,str_node_array[in].str);
- printf("str_node_array[%d].num:%d\n",in,str_node_array[in].num);
- #endif
- }
- }
- in++;
- buf = NULL;
- }
- #ifdef DEBUG
- printf("---------------------2222222222222222222222222222222222 str_node_array[0].str = %s\n",str_node_array[0].str);
- #endif
- //#if 0
- int count = 0;
- int j = 0;
- str_node tmpnode;
- for(; count TIMES; count++)
- {
- /* upper bubble */
- for(; j TIMES - count; j++)
- {
- if(str_node_array[j].num str_node_array[j+1].num)
- {
- strcpy(tmpnode.str,str_node_array[j].str);
- tmpnode.num = str_node_array[j].num;
- strcpy(str_node_array[j].str,str_node_array[j+1].str);
- str_node_array[j].num = str_node_array[j+1].num;
- strcpy(str_node_array[j+1].str,tmpnode.str);
- str_node_array[j+1].num = tmpnode.num;
- }
- }
- j = 0;
- }
- //#endif
- #ifdef DEBUG
- printf("---------------------3333333333333333333333333333333333\n");
- #endif
- j = 0;
- int len = 0;
- memset(fout,0,300);
- for(; j TIMES; j++)
- {
- // strcpy(fout+j,str_node_array[j].str); // The wrong
- len += sprintf(fout+len,"%s \n",str_node_array[j].str);
- printf("--------------------- %d,str_node_array[%d].str = %s,str_node_array[j].num = %d\n"
- ,j,j,str_node_array[j].str,str_node_array[j].num);
- }
- *(fout+len) = '\0';
- printf("After sort the string\n%s\n",fout);
- return 0;
-
}
-
-
int main()
-
{
- FILE *fp;
- char write_buf[100];
- char read_buf[300];
- char out_buf[300];
- int count = 0;
- memset(write_buf,0,100);
- memset(read_buf,0,300);
- memset(out_buf,0,300);
- fp = fopen("in.txt","w+");
- if(fp == NULL)
- {
- perror("fopen");
- return;
- }
- /* Write to file */
- srand( (unsigned int)time(0));
- for(; count TIMES; count++)
- {
- sprintf(write_buf,"Name %d \n",rand()%100);
- fwrite(write_buf,1,strlen(write_buf),fp);
- }
- fseek(fp,0L,SEEK_END);
- int buf_len = ftell(fp);
- fseek(fp,0L,SEEK_SET); // => rewind(fp);
- /* Read from file */
- fread(read_buf,1,buf_len,fp);
- read_buf[buf_len] = '\0';
- #ifdef DEBUG
- printf("%s",read_buf);
- #endif
- /* sort and output to out.txt */
- #ifdef DEBUG
- printf("----------------------------------------------\n");
- #endif
- fsort(read_buf,out_buf);
- #ifdef DEBUG
- printf("==============================================\n");
- #endif
- FILE *stream;
- stream = fopen("out.txt","w+");
- if(stream == NULL)
- {
- perror("fopen");
- return;
- }
- fwrite(out_buf,1,strlen(out_buf),stream);
- #ifdef DEBUG
- printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
- #endif
- fclose(fp);
- fclose(stream);
- return 0;
- }
二、运行效果
图1 随机生成的in.txt文件
图2 排序后输出的out.txt文件
三、几个重要说明
要实现这个功能,涉及随机数据的生成、文件的读写、数据排序、字符串的分割与合并。下面这段代码为其中的一个关键。
实现数据分割的关键代码。
-
while((p[in] = strtok_r(buf,"\n",&outer_ptr)) != NULL && in TIMES)
- {
- buf = p[in];
- strcpy(str_node_array[in].str,buf);
- if( (strtok_r(buf," ",&inner_ptr) ) != NULL )
- {
- if( (p_num = strtok_r(NULL," ",&inner_ptr) ) != NULL)
- {
- str_node_array[in].num = atoi(p_num);
- #ifdef DEBUG
- printf("str_node_array[%d].str:%s\n",in,str_node_array[in].str);
- printf("str_node_array[%d].num:%d\n",in,str_node_array[in].num);
- #endif
- }
- }
- in++;
- buf = NULL;
- }
(1)、本例数据特点
- Name 96
- Name 93
- Name 83
- Name 81
- Name 74
- Name 70
- Name 66
- Name 55
- Name 54
- Name 52
从in.txt读出来的字符串,先要根据’\n’进行行分割,再根据’ ’进行行中分割。这里使用普通的strtok函数是实现不了的。参考另外一篇博文《strtok的缺陷》。
(2)、strtok_r()函数
strtok_r()是系统专门为解决这个问题而设计的函数。参数列表:
p_str = strtok_r(buf,"\n",&outer_ptr))
buf : 要分割的字符串指针;
“\n”: 分割符;
&outer_ptr : 指向被分割成的后段字符串的指针的地址。
p_str :指向被分割成的前段字符串的指针。