>第 25 章 C标准库>标准I/O库函数>本节综合练习

tianyebj tianyebj@gmail.com
2009-10-19 13:48:36

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define N 50
void time_print(FILE *fp, int seq)
{
        time_t now = time(NULL);
        struct tm *tm_now = localtime(&now);
        char buf[N];
        sprintf(buf, "%d ", seq);
        strftime(buf + strlen(buf), N, "%Y-%m-%d %H:%M:%S", tm_now);
        fprintf(fp, "%s\n", buf);
        fflush(fp);
}

int main(void)
{
        FILE *fp;
        if ((fp = fopen("test.txt", "r+")) == NULL) {
                perror("test.txt");
                exit(1);
        }
	char buf[N] = {0};
        while(fgets(buf, N, fp) != NULL);
        int seq = 0;
        if (strcmp(buf, "") == 0) {
                seq = 0;
        } else {
                if (sscanf(buf, "%d", &seq) != 1) {
                        printf("scanf error!");
                        exit(1);
                }
        }
        while (1) {
                time_print(fp, ++seq);
                sleep(1);
        }

        fclose(fp);
}


吴书杰 wsj3000@gmail.com
2010-03-30 17:39:28

写成了,好累~~~:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
	const int BUFF_SIZE = 64;
	FILE *fp = NULL;
	int count = 0, offset = 0;
	char buff[128];
	memset(buff, '\0', BUFF_SIZE);
	time_t tt;
	struct tm *now;
	if((fp=fopen("./test.txt", "a+")) == NULL){
		perror("./test.txt:");
		exit(1);
	}

	while(fgets(buff, BUFF_SIZE, fp) != NULL);
	count = atoi(buff);
	while(1){
		tt = time(NULL);
		now = localtime(&tt);
		snprintf(buff, BUFF_SIZE, "%d ", ++count);
		offset = strlen(buff);
		strftime(buff + strlen(buff), BUFF_SIZE-offset,
				"%Y-%m-%d %H:%M:%S", now);
		fputs(buff, fp);
		fputs("\n", fp);
		fflush(fp);
		printf("%s\n", buff);
		sleep(1);
	}

	fclose(fp);
	return 0;
}


吴书杰 wsj3000@gmail.com
2010-03-31 13:51:41

第二题答案:
上班部分:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>

#define BUFF_MAX 256
#define SECT_NM_MAX 128

typedef enum {NO, YES} yesorno_e;
typedef enum {OUT, GETINTO, IN, GETOUT} sect_e;
typedef struct{
	int count; //current line number of ".ini" file
	yesorno_e anno; //1:this is a annotation;
	sect_e sect;
	//out:out of section  enter:enter section
	//in:in section  out:exit section
	char sect_nm[SECT_NM_MAX]; //section name
	char *keyp; //key name
	char *valp; //value
	char *annop; //the pointer to annotation;
}pps_t; // status generated by preprocessor, here is lpreproc();

int lpreproc(char * buff, FILE *fp, pps_t *st);
//return -1 when reach EOF;
int lgenxml(const char * buff, FILE *fp, const pps_t *st);

int main(int argc, char * argv[])
{
	pps_t st = {0, NO, OUT, {'\0'}, NULL, NULL, NULL};
	char buff[BUFF_MAX] = {'\0'};
	FILE *fppre, *fpgen;

	if(argc != 3){
		fputs("arguments error!\n", stderr);
		exit(2);
	}
	if((fppre=fopen(argv[1], "r")) == NULL){
		perror(argv[1]);
		exit(1);
	}
	if((fpgen=fopen(argv[2], "a+")) == NULL){
			perror(argv[2]);
			exit(1);
	}

	while(lpreproc(buff, fppre, &st) != -1){
		lgenxml(buff, fpgen, &st);
	}
	st.sect == IN || st.sect == GETINTO ? st.sect=GETOUT : 0;
	lgenxml(buff, fpgen, &st);

	fclose(fppre), fclose(fpgen);
	return 0;
}


吴书杰 wsj3000@gmail.com
2010-03-31 13:52:42

第二题,下半部分:

#define is_space(x) (x == ' ' || x == '\t')
#define syntax_error(x) \
	do{ \
		fprintf(stderr, "syntax error in line: %d.\n", x); \
		exit(3); \
	}while(0)

int lpreproc(char * buff, FILE *fp, pps_t *st)
{
	int i;
	if(fgets(buff, BUFF_MAX, fp) == NULL)
		return -1;

	(st->count)++;
	st->anno = 0;
	for(; is_space(buff[0]); buff++);
	switch(buff[0]){
	case '\n' :
		(st->sect == GETOUT) ? st->sect = OUT : 1;
		(st->sect == GETINTO || st->sect == IN) ? st->sect = GETOUT : 0;
		break;
	case ';' :
		for(i=1; buff[i]!='\n'; i++);
		buff[i] = '\0';
		st->annop = &buff[1];
		st->anno = YES;
		st->sect == GETOUT ? st->sect=OUT : 0;
		break;
	case '[' :
		buff++;
		for(; is_space(buff[0]); buff++);
		for(i=0; buff[i]!=']' && buff[i]!='\n'; i++){
			buff[i] == ' ' ? buff[i]='\0' : 0;
		}
		if(buff[i] != ']'){
			syntax_error(st->count);
		}
		buff[i] = '\0';
		strncpy(st->sect_nm, &buff[0], SECT_NM_MAX); // section name
		st->sect = GETINTO;
		break;
	default:
		for(i=0; buff[i]!='=' && buff[i]!='\n'; i++){
			buff[i] == ' ' ? buff[i]='\0' : 0;
		}
		if(buff[i] != '='){
				syntax_error(st->count);
		}
		buff[i] = '\0';
		st->keyp = &buff[0]; //key

		for(i++; is_space(buff[i]); i++);
		buff = &buff[i];
		for(i=0; buff[i]!='\n'; i++);
		buff[i] = '\0';
		st->valp = &buff[0]; //val
		st->sect = IN;
		break;
	}

	return 0;
}

int lgenxml(const char * buff, FILE *fp, const pps_t *st)
{
	if(st->anno == YES){
		st->sect == GETINTO || st->sect == IN ? fprintf(fp, "\t") : 0;
		fprintf(fp, "<!-- %s -->\n", st->annop);
		return 0;
	}else{
		switch(st->sect){
		case OUT :
			fprintf(fp, "\n");
			break;
		case GETINTO :
			fprintf(fp, "<%s>\n", st->sect_nm);
			break;
		case IN :
			fprintf(fp, "\t<%s>%s</%s>\n",
					st->keyp, st->valp, st->keyp);
			break;
		case GETOUT :
			fprintf(fp, "</%s>\n\n", st->sect_nm);
			break;
		}
	}
	return 0;
}


JerryWang kingwrcy@qq.com http://dotcloud.sonyejin.tk/
2011-08-29 11:02:14

第一题:

#include <stdio.h>
#include <time.h>
//Last Change:  2011-08-29 09:39:09  ===>by JerryWang  
int read_last_line_first_number(FILE* fp) {
	char year[15],time[15];
    int num = 0;
    fseek(fp,0L,SEEK_SET);
    while(fscanf(fp,"%d %s %s\n",&num,year,time) == 3);
    return num;
}
int main(int argc, const char *argv[]){
    FILE *fp ;
    int errorno,c = 0;
    char str[20];
    if((fp = fopen("test.log","a+")) == NULL){
        perror("read file test.log");
        return 0;
    }
    errorno = fseek(fp,-23L,SEEK_END);
    if (errorno!=0) perror("seek file test.log");
    c = read_last_line_first_number(fp)+1;
    printf("begin with %d\n",c);
    fseek(fp,0L,SEEK_SET);
    while (1) {
        time_t now;
        struct tm *now_tm;
        time(&now);
        now_tm = localtime(&now);
        size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp);
        strftime(str,sizeof(str),"%Y-%m-%d %H:%M:%S",now_tm);
        int err = fprintf(fp,"%d %s\n",c++,str);
        fseek(fp,20,SEEK_CUR);
        if(err < 0 ){
            perror("write log fail");
            break;
        }
        sleep(1);
    }
    fseek(fp,0L,SEEK_SET);
    fclose(fp);
    return 0;
}


chen liang epstein_2002@yahoo.com.cn
2011-11-04 10:24:53

第一题答案:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
	FILE *testfile;
	time_t timer;
	struct tm *tblock;
	unsigned long index=0;
	char buff[1024],tmpstr[32];
	testfile=fopen("test.txt","a+");
	if(!testfile)
	{
		perror("open test.txt failed");
		return 0;
	}
	
	while(fgets(buff,1024,testfile)!=NULL)
	{
		if(strlen(buff)>0)
			sscanf(buff,"%d %s %s",&index,tmpstr,tmpstr);
	}
	
	while(1)
	{
		timer=time(NULL);
		tblock=localtime(&timer);
		index++;
		fprintf(testfile,"%d %4d-%02d-%02d %02d:%02d:%02d\n",index,tblock->tm_year+1900,\
				tblock->tm_mon+1,tblock->tm_mday,tblock->tm_hour,tblock->tm_min,tblock->tm_sec);
		fflush(testfile);
		sleep(1);
		
	}
	fclose(testfile);
		
}
欢迎点评!谢谢!


chen liang epstein_2002@yahoo.com.cn
2011-11-07 16:37:39

第二题答案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR_LEN 1024
char *trim(char *str)
{
	char *str_old=str,*new_str;
	
	if(!str)
		return NULL;
	
	if(strlen(str)==0)
		return str;
	
	new_str=malloc(strlen(str)+1);
	if(!new_str)
		return NULL;
	
	while(*str_old!='\0' && (*str_old==' '||*str_old=='\t'))
	{
		str_old++;
	}
	
    strcpy(new_str,str_old);
	
	strcpy(str,new_str);
    str_old=str+strlen(str)-1;	
	while((str_old>str) && (*str_old==' '||*str_old=='\t'||*str_old=='\r'||*str_old=='\n'))
	{
		*str_old='\0';
		str_old--;
		if(*str_old!=' ' && *str_old!='\t' && *str_old!='\r' && *str_old!='\n')
			break;
	}
	free(new_str);
	return str;
}

int parse_ini_to_xml(const char *inistr,const char *xmlstr)
{
	char	buffline[MAX_STR_LEN];
	FILE	*inifile,*xmlfile;
	char	secName[MAX_STR_LEN]="\0";
	char	*posleft,*posright;
	char	key[MAX_STR_LEN],value[MAX_STR_LEN];
	if(!inistr||!xmlstr)
	{
		printf("Error:parse_ini_to_xml's input is null!\n");
		return -1;
	}
	
	inifile=fopen(inistr,"r");
	if(!inifile)
	{
		perror("open ini file failed");
		return -2;
	}
	
	xmlfile=fopen(xmlstr,"w");
	if(!xmlfile)
	{
		perror("open xml file failed");
		return -3;
	}
	
	while(fgets(buffline,MAX_STR_LEN,inifile)!=NULL)
	{
		trim(buffline);
		if(buffline[0]==';')
			fprintf(xmlfile,"<!-- %s -->\n",buffline+1);
		else if(buffline[0]=='[')
		{
			posleft=strchr(buffline,'[');
			posright=strchr(buffline,']');
			if(posright && posright>posleft)
			{
				*posright='\0';
				strcpy(secName,posleft+1);
				trim(secName);
				fprintf(xmlfile,"<%s>\n",secName);
			}			
		}
		else if((posleft=strchr(buffline,'='))!=NULL && posleft>&buffline[0])
		{
			*posleft='\0';
			strcpy(key,buffline);
			strcpy(value,posleft+1);
			trim(key);
			trim(value);
			fprintf(xmlfile,"		<%s>%s</%s>\n",key,value,key);
		}
		else if(strlen(secName)>0)
		{
			fprintf(xmlfile,"</%s>\n\n",secName);
			secName[0]='\0';
		}
		else
		{
			fprintf(xmlfile,"\n");
		}
	}	
    if(strlen(secName)>0)
	{
		fprintf(xmlfile,"</%s>\n",secName);
	}
	fclose(inifile);
	fclose(xmlfile);
	return 0;
}
int main(void)
{
    return 	 parse_ini_to_xml("1.ini","1.xml");
	
}
	
欢迎点评!谢谢!


peerben benzhemin@gmail.com
2011-12-21 09:23:25

习题一:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE 50

int main(void){
	FILE *fp;
	char buf[MAX_LINE];
	int index = 0;
	int year, month, day;
	int hour, minute, second;

	if((fp=fopen("test.txt", "r+")) == NULL){
		perror("open test.txt error");
		exit(1);
	}

	fseek(fp, 0, SEEK_SET);
	while(fgets(buf, MAX_LINE, fp) != NULL){
		sscanf(buf, "%d %d-%d-%d %d:%d:%d", &index, &year, &month, 
				&day, &hour, &minute, &second);
		printf("index:%d %s\n", index, buf);
		fflush(stdout);
	}

	while(1){
		index++;
		time_t tt = time(NULL);
		struct tm *tnow= localtime(&tt);
		fflush(stdout);
		sprintf(buf, "%d %d-%d-%d %d:%d:%d\n", index, (1900+tnow->tm_year), tnow->tm_mon, tnow->tm_mday,
				tnow->tm_hour, tnow->tm_min, tnow->tm_sec);
		fseek(fp, 0, SEEK_END);
		fputs(buf, fp);
		fflush(fp);
		sleep(1);
	}

	fclose(fp);

	return 0;
}

欢迎指正


peerben benzhemin@gmail.com
2011-12-22 09:52:46

第二题答案:

第二题的关键在于解析,把解析做好了,输出xml变的很简单了。

写的有点冗长,欢迎指正。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_LINE 100
#define TRUE 1
#define FALSE 0

typedef struct _cmmt_node{
	char *comment;
	struct _cmmt_node *next;
} cmmt_node;

typedef struct _child_node{
	cmmt_node *header;
	char *key;
	char *value;
	struct _child_node *next;
} child_node;

typedef struct _root_node{
	cmmt_node *header;
	char *root_name;
	child_node *child;
	struct _root_node *next;
} root_node;


char buf[MAX_LINE];


void remove_newline(){
	int cmmt_len = strlen(buf);
	if(buf[cmmt_len-1] == '\n'){
		buf[cmmt_len-1] = '\0';
	}
}

void process_cmmt(root_node *root){
	remove_newline();	

	cmmt_node *current;
	if((current=root->header) == NULL){
		current = root->header = (cmmt_node *)malloc(sizeof(cmmt_node));
		if(current == NULL){
			perror("malloc error!");
		}
	}else{
		while(current->next != NULL){
			current = current->next;
		}
		current->next = (cmmt_node *)malloc(sizeof(cmmt_node));
		if(current->next == NULL){
			perror("malloc error!");
		}
		current = current->next;
	}

	current->comment = (char *)malloc(strlen(buf+1)+1);
	strcpy(current->comment, buf+1);
}

void process_root(root_node *root){
	remove_newline();

	char *pc = buf+1;
	while(*pc!='\0' && *pc!=']'){
		pc++;
	}
	if(*pc == ']'){
		*pc = '\0';
	}

	root_node *current = root;
	while(current->next != NULL){
		current = current->next;
	}
	current->root_name = (char *)malloc(strlen(buf+1)+1);
	strcpy(current->root_name, buf+1);
}

void process_child(root_node *root){
	remove_newline();

	char *key = strtok(buf, "= ");
	char *value = strtok(NULL, "= ");

	child_node *current;
	if((current=root->child) == NULL){
		current = root->child = (child_node *)malloc(sizeof(child_node));
		if(current == NULL){
			perror("malloc error!");
		}
	}else{
		while(current->next != NULL){
			current = current->next;
		}
		current->next = (child_node *)malloc(sizeof(child_node));
		if(current == NULL){
			perror("malloc error!");
		}
		current = current->next;
	}
	current->key = (char *)malloc(strlen(key)+1);
	if(current->key == NULL){
		perror("malloc error!");
	}
	strcpy(current->key, key);

	current->value = (char *)malloc(strlen(value)+1);
	if(current->value == NULL){
		perror("malloc error!");
	}
	strcpy(current->value, value);
}


peerben benzhemin@gmail.com
2011-12-22 09:54:27

第二题 下半部分

 void malloc_root(int *new_section, root_node **root, root_node **current_outer){
	root_node *current;

	if(*new_section){
		*new_section = FALSE;

		if(*root == NULL){
			current = *root = (root_node *)calloc(1, sizeof(root_node));
			if(root == NULL){
				perror("malloc error!");
				exit(1);
			}
		}else{
			current = *root;
			while(current->next != NULL){
				current = current->next;
			}
			root_node *new_node = (root_node *)calloc(1, sizeof(root_node));
			if(new_node == NULL){
				perror("malloc error!");
				exit(1);
			}
			current->next = new_node;
			current = current->next;
		}
		*current_outer = current;
	}
}

root_node *parse_ini(char *fname){
	FILE *fp;
	root_node *root = NULL;
	root_node *current = NULL;
	int new_section = TRUE;

	if((fp=fopen(fname, "r")) == NULL){
		perror("file does not exist!");
		exit(1);
	}

	while(fgets(buf, MAX_LINE, fp) != NULL){
		char *p = buf;
		while(*p!='\0' && (*p==' ' || *p==9)){
			p++;
		}

		//key-value child element
		if(isalpha(*p)){
			process_child(current);
		}else{
			if(*p == ';'){
				malloc_root(&new_section, &root, &current);
				process_cmmt(current);
			}else if(*p == '['){
				malloc_root(&new_section, &root, &current);
				process_root(current);
			}else{
				if(*p == '\n'){
					new_section = TRUE;
				}
			}
		}
	}


	fclose(fp);
	return root;
}

void print_root(root_node *root){
	while(root != NULL){
		cmmt_node *cmmt_h =root->header;
		while(cmmt_h!=NULL){
			printf("%s\n", cmmt_h->comment);
			cmmt_h = cmmt_h->next;
		}

		printf("%s\n", root->root_name);

		child_node *child_n = root->child;
		while(child_n!=NULL){
			printf("%s=%s\n", child_n->key, child_n->value);
			child_n = child_n->next;
		}

		root = root->next;
	}
}


void fmt_xml_child(char *key, char *value){
	sprintf(buf, "    <%s>%s</%s>\n", key, value, key);
}

void fmt_comment(char *comment){
	sprintf(buf, "<!-- %s -->\n", comment);
}

void fmt_tag_start(char *tag){
	sprintf(buf, "<%s>\n", tag);
}

void fmt_tag_end(char *tag){
	sprintf(buf, "</%s>\n", tag);
}


void write_xml(char *fname, root_node *root){
	FILE *fp;

	if((fp = fopen(fname, "w"))==NULL){
		perror("file doesn't exist!");
		exit(1);
	}

	while(root != NULL){
		cmmt_node *cmmt_h = root->header;
		while(cmmt_h != NULL){
			fmt_comment(cmmt_h->comment);
			fputs(buf, fp);
			cmmt_h = cmmt_h->next;
		}

		fmt_tag_start(root->root_name);
		fputs(buf, fp);

		child_node *child_n = root->child;
		while(child_n != NULL){
			fmt_xml_child(child_n->key, child_n->value);
			fputs(buf, fp);
			child_n = child_n->next;
		}

		fmt_tag_end(root->root_name);
		fputs(buf, fp);

		fputc('\n', fp);
		fflush(fp);

		root = root->next;
	}

	fclose(fp);
}



peerben benzhemin@gmail.com
2011-12-22 09:55:15

第二题 结尾

void free_root(root_node *root){
	root_node *p_root = root;

	while(p_root != NULL){
		root_node *p_root_n = p_root->next;

		cmmt_node *p_header = p_root->header;
		while(p_header != NULL){
			cmmt_node *p_next = p_header->next;
			free(p_header->comment);
			free(p_header);
			p_header = p_next;
		}

		child_node *child_n = p_root->child;
		while(child_n != NULL){
			child_node *child_n_n = child_n->next;
			free(child_n->key);
			free(child_n->value);
			free(child_n);
			child_n = child_n_n;
		}

		free(p_root->root_name);
		free(p_root);
		p_root = p_root_n;
	}
}

int main(void){
	char *fini = "settings.ini";
	char *fxml = "settings.xml";


	root_node *root = parse_ini(fini);
	print_root(root);
	write_xml(fxml, root);
	free_root(root);

	return 0;
}


如果您有建设性意见,哪怕只是纠正一个错别字,也请不吝赐教,您留下的姓名和email将会出现在本书前言的致谢中。再次感谢您的宝贵意见!