⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quiz.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Jim R. Oldroyd at The Instruction Set and Keith Gabryelski at * Commodore Business Machines. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1991, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)quiz.c	8.2 (Berkeley) 1/3/94";#endif /* not lint */#include <sys/types.h>#include <errno.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "quiz.h"#include "pathnames.h"static QE qlist;static int catone, cattwo, tflag;static u_int qsize;char	*appdstr __P((char *, char *, size_t));void	 downcase __P((char *));void	 err __P((const char *, ...));void	 get_cats __P((char *, char *));void	 get_file __P((char *));char	*next_cat __P((char *));void	 quiz __P((void));void	 score __P((u_int, u_int, u_int));void	 show_index __P((void));void	 usage __P((void));intmain(argc, argv)	int argc;	char *argv[];{	register int ch;	char *indexfile;	indexfile = _PATH_QUIZIDX;	while ((ch = getopt(argc, argv, "i:t")) != EOF)		switch(ch) {		case 'i':			indexfile = optarg;			break;		case 't':			tflag = 1;			break;		case '?':		default:			usage();		}	argc -= optind;	argv += optind;	switch(argc) {	case 0:		get_file(indexfile);		show_index();		break;	case 2:		get_file(indexfile);		get_cats(argv[0], argv[1]);		quiz();		break;	default:		usage();	}	exit(0);}voidget_file(file)	char *file;{	register FILE *fp;	register QE *qp;	size_t len;	char *lp;	if ((fp = fopen(file, "r")) == NULL)		err("%s: %s", file, strerror(errno));	/*	 * XXX	 * Should really free up space from any earlier read list	 * but there are no reverse pointers to do so with.	 */	qp = &qlist;	qsize = 0;	while ((lp = fgetln(fp, &len)) != NULL) {		if (qp->q_text && qp->q_text[strlen(qp->q_text) - 1] == '\\')			qp->q_text = appdstr(qp->q_text, lp, len);		else {			if ((qp->q_next = malloc(sizeof(QE))) == NULL)				err("%s", strerror(errno));			qp = qp->q_next;			lp[len - 1] = '\0';			if ((qp->q_text = strdup(lp)) == NULL)				err("%s", strerror(errno));			qp->q_asked = qp->q_answered = FALSE;			qp->q_next = NULL;			++qsize;		}	}	(void)fclose(fp);}voidshow_index(){	register QE *qp;	register char *p, *s;	FILE *pf;	if ((pf = popen(_PATH_PAGER, "w")) == NULL)		err("%s: %s", _PATH_PAGER, strerror(errno));	(void)fprintf(pf, "Subjects:\n\n");	for (qp = qlist.q_next; qp; qp = qp->q_next) {		for (s = next_cat(qp->q_text); s; s = next_cat(s)) {			if (!rxp_compile(s))				err("%s", rxperr);			if (p = rxp_expand())				(void)fprintf(pf, "%s ", p);		}		(void)fprintf(pf, "\n");	}	(void)fprintf(pf, "\n%s\n%s\n%s\n","For example, \"quiz victim killer\" prints a victim's name and you reply","with the killer, and \"quiz killer victim\" works the other way around.","Type an empty line to get the correct answer.");	(void)pclose(pf);}voidget_cats(cat1, cat2)	char *cat1, *cat2;{	register QE *qp;	int i;	char *s;	downcase(cat1);	downcase(cat2);	for (qp = qlist.q_next; qp; qp = qp->q_next) {		s = next_cat(qp->q_text);		catone = cattwo = i = 0;		while (s) {			if (!rxp_compile(s))				err("%s", rxperr);			i++;			if (rxp_match(cat1))				catone = i;			if (rxp_match(cat2))				cattwo = i;			s = next_cat(s);		}		if (catone && cattwo && catone != cattwo) {			if (!rxp_compile(qp->q_text))				err("%s", rxperr);			get_file(rxp_expand());			return;		}	}	err("invalid categories");}voidquiz(){	register QE *qp;	register int i;	size_t len;	u_int guesses, rights, wrongs;	int next;	char *answer, *s, *t, question[LINE_SZ];	srandom(time(NULL));	guesses = rights = wrongs = 0;	for (;;) {		if (qsize == 0)			break;		next = random() % qsize;		qp = qlist.q_next;		for (i = 0; i < next; i++)			qp = qp->q_next;		while (qp && qp->q_answered)			qp = qp->q_next;		if (!qp) {			qsize = next;			continue;		}		if (tflag && random() % 100 > 20) {			/* repeat questions in tutorial mode */			while (qp && (!qp->q_asked || qp->q_answered))				qp = qp->q_next;			if (!qp)				continue;		}		s = qp->q_text;		for (i = 0; i < catone - 1; i++)			s = next_cat(s);		if (!rxp_compile(s))			err("%s", rxperr);		t = rxp_expand();		if (!t || *t == '\0') {			qp->q_answered = TRUE;			continue;		}		(void)strcpy(question, t);		s = qp->q_text;		for (i = 0; i < cattwo - 1; i++)			s = next_cat(s);		if (!rxp_compile(s))			err("%s", rxperr);		t = rxp_expand();		if (!t || *t == '\0') {			qp->q_answered = TRUE;			continue;		}		qp->q_asked = TRUE;		(void)printf("%s?\n", question);		for (;; ++guesses) {			if ((answer = fgetln(stdin, &len)) == NULL) {				score(rights, wrongs, guesses);				exit(0);			}			answer[len - 1] = '\0';			downcase(answer);			if (rxp_match(answer)) {				(void)printf("Right!\n");				++rights;				qp->q_answered = TRUE;				break;			}			if (*answer == '\0') {				(void)printf("%s\n", t);				++wrongs;				if (!tflag)					qp->q_answered = TRUE;				break;			}			(void)printf("What?\n");		}	}	score(rights, wrongs, guesses);}char *next_cat(s)	register char *	s;{	for (;;)		switch (*s++) {		case '\0':			return (NULL);		case '\\':			break;		case ':':			return (s);		}	/* NOTREACHED */}char *appdstr(s, tp, len)	char *s;	register char *tp;	size_t len;{	register char *mp, *sp;	register int ch;	char *m;	if ((m = malloc(strlen(s) + len + 1)) == NULL)		err("%s", strerror(errno));	for (mp = m, sp = s; *mp++ = *sp++;);	if (*(mp - 1) == '\\')		--mp;	while ((ch = *mp++ = *tp++) && ch != '\n');	*mp = '\0';	free(s);	return (m);}voidscore(r, w, g)	u_int r, w, g;{	(void)printf("Rights %d, wrongs %d,", r, w);	if (g)		(void)printf(" extra guesses %d,", g);	(void)printf(" score %d%%\n", (r + w + g) ? r * 100 / (r + w + g) : 0);}voiddowncase(p)	register char *p;{	register int ch;	for (; ch = *p; ++p)		if (isascii(ch) && isupper(ch))			*p = tolower(ch);}voidusage(){	(void)fprintf(stderr, "quiz [-t] [-i file] category1 category2\n");	exit(1);}#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endifvoid#if __STDC__err(const char *fmt, ...)#elseerr(fmt, va_alist)	char *fmt;        va_dcl#endif{	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	(void)fprintf(stderr, "quiz: ");	(void)vfprintf(stderr, fmt, ap);	va_end(ap);	(void)fprintf(stderr, "\n");	exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -