Feb 14

trans程序的源代码在Msys下用gcc编译调试通过。

使用说明:trans  [-r/-s] srcfile objfile

    其中,-R 将摩斯码翻译成英文;
          -S 将英语翻译成摩斯码。
          srcfile为需要翻译的文本文件。运行成功后结果会保存在objfile文件中。

    注意:若是翻译英文,须保证所有字母均为大写字母。且标点符号仅可为“.”和“,”

代码已上传至github https://github.com/longqzh/MorseCode_Translator

/* *******************************
 *
 * Translator for Morse Code
 *
 * Author: Long Qianzhi
 * Date:2010/1/28
 *
 * *******************************/

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

#define MAX 39

struct table{
	char letter;
	char mor[8];
}table[]={
	{'A',".-"},{'B',"-..."},{'C',"-.-."},
	{'D',"-.."},{'E',"."},{'F',"..-."},
	{'G',"--."},{'H',"...."},{'I',".."},
	{'J',".---"},{'K',"-.-"},{'L',".-.."},
	{'M',"--"},{'N',"-."},{'O',"---"},
	{'P',".--."},{'Q',"--.-"},{'R',".-."},
	{'S',"..."},{'T',"-"},{'U',"..-"},
	{'V',"...-"},{'W',".--"},{'X',"-..-"},
	{'Y',"-.--"},{'Z',"--.."},{'0',"-----"},
	{'1',".----"},{'2',"..---"},{'3',"...--"},
	{'4',"....-"},{'5',"....."},{'6',"-...."},
	{'7',"--..."},{'8',"---.."},{'9',"----."},
	{'.',".-.-.-"},{',',"--..--"},{' ',".--.-."},
	{'\n',""}
};

FILE *infp=NULL, *outfp=NULL;

void check_file(char *in, char *out)
{
	if((infp=fopen(in,"r"))==NULL){
		printf("\nCan't open source file : %s\n", in);
		exit(1);
	}
	else if ((outfp=fopen(out,"w"))==NULL){
		printf("\nCan't open output file : %s\n", out);
		exit(1);
	}
	return;
}

int file_size(FILE *fp)
{
	int fsize=0;
	char c;
	while((c=fgetc(fp))!=EOF)
		fsize++;
	rewind(fp);
	return fsize;
}

char* make_buf(int n)
{
	char *pstr;
	pstr=(char *)malloc(n*sizeof(char));
	if(pstr==NULL){
		printf("\nMalloc failed!\n");
		exit(1);
	}
	return pstr;
}

void m2t()
{
	char *buffer;
	int fnum,n=0,i=0;
	char tmp[8]="";

	/* Read all of the data from srcfile to buffer.*/
	fnum=file_size(infp);
	buffer=make_buf(fnum+1);
	if((fread(buffer,sizeof(char),fnum,infp))!=fnum){
		printf("\nSomething wrong about reading file!\n");
		exit(1);
	}
	*(buffer+fnum)='\0';
	fclose(infp);

	printf("%s\n",buffer);fflush(stdout);

	while(*buffer!='\0'){

		/* Read a word from buffer to tmp.*/
		while(*buffer!=' ' && *buffer!='\0'){
			tmp[n++]=*buffer++;
			if(n>7){
				tmp[7]='\0';
				printf(" %s : Bad MorseCode!\n", tmp);
				exit(1);
			}
		}
		tmp[n]='\0';
		n=0; 
		printf("%s\t",tmp);fflush(stdout);
		

		while(strcmp(tmp,table[i++].mor)){
			if(i>=MAX && *(buffer+1)!='\0'){
				printf(" %s : CANNOT find it!\n", tmp);
				exit(1);
			}
		}

		fputc(table[--i].letter,outfp);
		printf("%c\t",table[i].letter);fflush(stdout);
		i=0;
		buffer++;
	}
	fclose(outfp);
	printf("The translated file is created.\n");
	fflush(stdout);
}

void t2m()
{
	char *buffer;
	int fnum,i=0;

	/* Read all of the data from srcfile to buffer.*/
	fnum=file_size(infp);

	buffer=make_buf(fnum+1);
	if((fread(buffer,sizeof(char),fnum,infp))!=fnum){
		printf("\nSomething wrong about reading file!\n");
		exit(1);
	}
	*(buffer+fnum)='\0';
	fclose(infp);

	printf("%s %d\n", buffer,(int)(*buffer));fflush(stdout);

	while(*buffer!='\0'){
		/* find the MorseCode according to character.*/
		while(*buffer!=table[i].letter){
			
			i++;
			fflush(stdout);
			if(i>MAX && *buffer!=EOF){
				printf(" %c %d: Bad character\n", *buffer,(int)(*buffer));
				exit(1);
			}
		}
		buffer++;
		printf("%c-->%s\t\n",table[i].letter,table[i].mor);fflush(stdout);

		fputs(table[i].mor,outfp);
		fputc(' ',outfp);
		i=0;
	}
	fclose(outfp);
	printf("The translated file is created.\n");
	fflush(stdout);
}

int main(int argc,char *argv[])
{
	if (argc!=4){
		printf("Usage: trans [-R/-S] srcfile outfile\n");
		printf("\n\t -r translate Morse to English.");
		printf("\n\t -s translate English to Morse.");
		printf("\n\t -h show this help information.\n");
		fflush(stdout);
		return 1;
	}

	if (!strcmp(argv[1],"-r") || !strcmp(argv[1],"-R")){
		check_file(argv[2],argv[3]);
		m2t();
	}
	else if (!strcmp(argv[1],"-s") || !strcmp(argv[1],"-S")){
		check_file(argv[2],argv[3]);
		t2m();
	}else{
		printf("You input wrong arguments!\n");
		printf("Please type \"trans -h\".\n");
		fflush(stdout);
	}
	return 0;
}
Dec 16

公布期末设计Smallshell的完整源代码:

 

/* *************************************************
 *
 *          Small shell on Unix/Linux
 *
 *   This shell finished all the functions which 
 *   are required. And I added new inner functions
 *   "help" and "exit" by myself.
 *  
 *   Enjoy it!
 *
 *   author: Longqianzhi 용성지 
 *   Stu_ID: 12094817
 *   data:   Dec/27/2010
 *
 * *************************************************/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>

#define MAX_CMD_ARG 10
#define MAX_CMD_LIST 10

const char *prompt = "# ";

char* cmdlist[MAX_CMD_LIST];
char* cmdargs[MAX_CMD_ARG];
char  cmdline[BUFSIZ];

void fatal(char *str);
void execute_cmd(char *cmd);
void execute_cmdline(char* cmdline);
int makeargv(char *s, const char *delimiters, 
	             char** argvp, int MAX_LIST);
void help();
void cd(char *path);
void catchint(int);
void join();                    /* Use one pipe to communication.*/
int join2();                    /* Use two pipe to communication.*/
int dpipe_test();               /* It's useless.Just for test.*/
void parse_filter(char *cmd);   /* A filter for argument*/ 


int main(int argc, char**argv){
	int i=0;
	static struct sigaction act;

	/*Cope with the signal*/

	act.sa_handler=catchint;
	sigfillset(&(act.sa_mask));
	sigaction(SIGINT,&act,NULL);
	sigaction(SIGQUIT,&act,NULL);

	while (1) {     
		fputs(prompt, stdout);
		fgets(cmdline, BUFSIZ, stdin);
		cmdline[ strlen(cmdline) -1] ='\0';

		execute_cmdline(cmdline);
		printf("\n");
	}
	return 0;
}

void fatal(char *str){
	perror(str);
	exit(1);
}

void execute_cmdline(char* cmdline){
	int count = 0;
	int i=0;
	count = makeargv(cmdline, "!", cmdlist, MAX_CMD_LIST);

    /* Execute the commands with different way.*/   

	/*Just a single command.*/
	if(count==1){
	
		/* First of all,try to make sure whether
		 * the command is "cd".
		 */
		if(cmdlist[0][0]=='c'&&cmdlist[0][1]=='d'){
			parse_filter(cmdlist[0]);  
			count = makeargv(cmdlist[0], " \t", cmdargs, MAX_CMD_ARG);
			if(!strcmp("cd",cmdargs[0])){
				if(chdir(cmdargs[1]))  fatal("cd");
				return;
			}
		}
	
		/* Fork a child process to run every
		 * commands except "cd" 
		*/
		 
		switch(fork())
		{
		case -1: fatal("fork error");
		case  0: execute_cmd(cmdlist[0]);
		default:
			wait(NULL);
			fflush(stdout);
		}
	}
	
	/*Execute two programs with a pipe.*/
	if(count==2){
		join();
	}

	/*Execute three programs with two pipes.*/
	if(count==3){
		join2();
	}

	/*There are too many commands*/
	if(count>=4){
		printf("Too many pipes!\n");
		return;
	}
}

/* *****************************************
 * Execute a single commands with arguments.
 *
 * *****************************************/
void execute_cmd(char *cmd){
	int i=0; 
	int count = 0;
	
	parse_filter(cmd);  
	count = makeargv(cmd, " \t", cmdargs, MAX_CMD_ARG);

	/* 
	 * Recognize some inner functions 
	 * like cd,help,exit and so on.
	 * Also you can add some new inner
	 * functions by yourself here.
	 *
	 */
	if(!strcmp("help",cmdargs[0])){
		help();
		return ;
	}

	if(!strcmp("exit",cmdargs[0])){
		kill(getppid(),SIGKILL); /*kill parent process*/
		raise(SIGKILL); /*kill myself*/
		exit(0);
	}

	execvp(cmdargs[0], cmdargs);
	fatal("exec error");
}

/* *****************************************
 *  Count the arguments'number in a command.
 *
 * ***************************************/
int makeargv(char *s, const char *delimiters, 
   					char** argvp, int MAX_LIST) {

	int i = 0;
	int numtokens = 0;
	char *snew = NULL;

	if( (s==NULL) || (delimiters==NULL) ) return -1;

	snew = s + strspn(s, delimiters);	
	if( (argvp[numtokens]=strtok(snew, delimiters)) == NULL )
	return numtokens;
	
	numtokens = 1;
	while(1){
		if( (argvp[numtokens]=strtok(NULL, delimiters)) == NULL)
			break;
		if(numtokens == (MAX_LIST-1)) return -1;
			numtokens++;
	}
	return numtokens;
}

/* *********************************
 * Inner fnuction: help().
 * Show some infomations to the stdin
 *
 ***********************************/
void help(){
	printf("\n  * *************************************** *");
	printf("\n  *                                         *");
	printf("\n  *         WELCOME TO SMALL SHELL !        *");
	printf("\n  *                                         *");
	printf("\n  * *************************************** *");
	printf("\n  *                                         *");
	printf("\n  *  There are 3 inner functions in shell.  *");
	printf("\n  *                                         *");
	printf("\n  *  1) cd :Change the current directory.   *");
	printf("\n  *  2) exit :Quit from the small shell.    *");
	printf("\n  *  3) help :Show this message for help.   *"); 
	printf("\n  *                                         *");
	printf("\n  *        IF YOU FIND ANY BUGS OR          *");
	printf("\n  *          HAVE ANY QUESTIONS             *");
	printf("\n  *                                         *");
	printf("\n  *    mail to me:longqianzhi@gmail.com     *");
	printf("\n  *                                         *");
	printf("\n  * *************************************** *\n");
	exit(0);
}


/* ***************************
 * Inner function:cd().
 * Change the current directory.
 *
 * ***************************/
 
void cd(char *path){
	if(chdir(path))
		fatal("cd");
}


/* ************************************
 * The function about act.sa_handler
 * If press the Ctrl+c, resume the shell.
 *
 * ************************************/
 
void catchint(int signo){
	printf("\nReceive a signo=%d\n",signo);
	printf("Returning to the shell\n");

	/* Init the cmdline Array.
	 * If not,the shell will try to run 
	 * commands in the memory.
	 */
	cmdline[0]='\0';
}


/* ************************************
 * An easy way to use double pipe.
 *
 * But this function is just for test and   
 * debug in the project,because I wrote  
 * a new one by myself. The new one is 
 * called "join2".
 *
 * ***********************************/

int dpipe_test(){

	/*build command string with normal format.*/

	char newstr[128];
	strcpy(newstr,cmdlist[0]);
	strcat(newstr,"|");
	strcat(newstr,cmdlist[1]);
	strcat(newstr,"|");
	strcat(newstr,cmdlist[2]);
	
	/*call system shell to run the commmands*/
	system(newstr);
	return 0;
}


/* **************************************
 * Delete special character from argument.
 * If there is any special charater,
 * this function will change them to '\32'
 *
 * ***************************************/
 
void parse_filter(char *cmd){
	int i=0;
	int CMAX=strlen(cmd);
	
	while(cmd[i]!=' '&&i<CMAX) i++;
	
	if((++i)<CMAX){
		if (cmd[i++]=='-')	{	
			while(cmd[i]!=' '&&i<CMAX){
			
				if(cmd[i]<'0'||(cmd[i]>'9'&&cmd[i]<'A')||
					(cmd[i]>'Z'&&cmd[i]<'a')||cmd[i]>'z'){

					char tmp=cmd[i-1];			
					cmd[i]=tmp;	
				}
				i++;
			}
		}
	}
	
}

/* ***********************************
 * Link the child process's stdout to
 * grandchild process's stdin with pipe.
 *
 * ***********************************/
 
void join(){
	int p[2],status;

	switch (fork()){
		case -1:fatal("1st fork call in join()");
		case 0:break;
		default:wait(&status);
				return;
	}
	
	/* Try to make a new pipe.*/
	if(pipe(p)==-1) fatal("pipe call in join()");

	switch(fork()){
		case -1:fatal("2nd fork call in join()");
		case 0:
				dup2(p[1],1);
				close(p[0]);
				close(p[1]);
				execute_cmd(cmdlist[0]);
				fatal("1st execvp call in join()");
		default:
				dup2(p[0],0);
				close(p[0]);
				close(p[1]);
				execute_cmd(cmdlist[1]);
				fatal("2nd execvp call in join()");
	}
}



/* *************************************
 * Link three child/grandchild processes 
 * one by one with two pipes.
 *
 * ************************************/

int join2(){
	int status,p1[2],p2[2];
	
	/*Test the double pipe.*/	
	if(dpipe_test()==0) return 0;  

	/* Grandparent process */
	switch(fork()){
		case -1:fatal("1st fork call");
		case 0:break;
		default:
			   wait(&status);
			   return status;
	}


	/* Parent process.Run the last command.*/

	if(pipe(p1)<0) fatal ("pipe call"); /*make a pipe.*/

	switch(fork()){
		case -1:fatal("2nd fork call");
		case 0:break;
		default:
			   dup2(p1[0],0);
			   close(p1[0]);
			   close(p1[1]);

			   execute_cmd(cmdlist[2]);
			   fatal("1st exec call");
	}
	
	/* Try to make a new pipe.*/

	if(pipe(p2)<0) fatal("pipe call"); 

	/* Child process.Run the second command.*/
	
	switch(fork()){
		case -1:fatal("3th fork call");
		case 0:break;
		default:
			   dup2(p1[1],1);
			   dup2(p2[0],0);
			   close(p1[0]);
			   close(p1[1]);
			   close(p2[0]);
			   close(p2[1]);

			   execute_cmd(cmdlist[1]);
			   fatal("2nd exec call");
	}

	/* Grandchild process.Run the first command.*/
	
	dup2(p2[1],1);
	close(p2[0]);
	close(p2[1]);

	execute_cmd(cmdlist[0]);
	fatal("3th exec call");

}