1. 程式人生 > >從0開始:getint()函式(類似於scanf函式)以及庫函式strncpy、strncat及strncmp函式的實現

從0開始:getint()函式(類似於scanf函式)以及庫函式strncpy、strncat及strncmp函式的實現

程式一:編寫getint(int *pn)函式

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

#define BUFSIZE 100
char buf[BUFSIZE];   /*用於ungetch函式的緩衝區*/
int bufp = 0; /*buf中下一個空閒位置*/

int getch(void);  /*取一個字元*/
void ungetch(int);  /*把字元壓回到輸入中*/

int getint(int *pn);
int main(void)
{
	int i,arr[3];
	for (i=0; i<3 && getint(&arr[i])!=EOF; ++i);
	for (i=0; i<3; ++i)
		printf("%d\n",arr[i]);
	return 0;
}

int getch(void)
{
	return (bufp>0)?buf[--bufp]:getchar();
}

void ungetch(int c) /*把字元壓回到輸入中*/
{
	if (bufp >= BUFSIZE)
		printf("ungetch: too many characters\n");
	else
		buf[bufp++] = c;
}

/*將輸入中的下一個整型數值賦值給*pn*/
int getint(int *pn)
{
	int c,sign;
	while ( isspace(c = getch())); /*跳過空白符*/
	if (!isdigit(c) && c!=EOF && c!='+' && c!= '-') 
	{
		ungetch(c);
		return 0;
	}
	sign = (c == '-')?-1:1;
	if (c == '+' || c== '-')
		c = getch();
	for (*pn=0; isdigit(c); c=getch())
		*pn = 10 * *pn + (c - '0');
	*pn *= sign;
	if (c != EOF)
		ungetch(c);
	return c;
}
程式二:實現庫函式strncpy、strncat 、strncmp,它們最多對引數字串中的前n個字元進行操作。例如,函式strncpy(s,t,n)將t中的最多n個字元複製到s中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BUF 16

char *mystrncpy(char *s, const char *ct, size_t n) 
{
	char *p;
	
	p = s;
	for (; n > 0 && *ct != '\0'; --n)
		*p++ = *ct++;
	for (; n > 0; --n)
		*p++ = '\0';
	return s;
}

char *mystrncat(char *s, const char *ct, size_t n) 
{
	char *p;
	
	p = s;
	while (*p != '\0')
		++p;
	for (; n > 0 && *ct != '\0'; --n)
		*p++ = *ct++;
	*p = '\0';
	return s;
}

int mystrncmp(const char *cs, const char *ct, size_t n) 
{
	while (n > 0 && *cs == *ct && *cs != '\0') 
	{
		++cs;
		++ct;
		--n;
	}
	if (n == 0 || *cs == *ct)
		return 0;
	if (*(unsigned char *) cs < *(unsigned char *) ct)
		return -1;
	return 1;
}

void test_ncpy(const char *str) 
{
	char std_buf[MAX_BUF];
	char liw_buf[MAX_BUF];

	memset(std_buf, 0x42, sizeof(std_buf));
	strncpy(std_buf, str, sizeof(std_buf));

	memset(liw_buf, 0x42, sizeof(liw_buf));
	mystrncpy(liw_buf, str, sizeof(liw_buf));

	if (memcmp(std_buf, liw_buf, sizeof(std_buf)) != 0) {
		fprintf(stderr, "liw_strncpy failed for <%s>\n", str);
		exit(EXIT_FAILURE);
	}
}

void test_ncat(const char *first, const char *second) 
{
	char std_buf[MAX_BUF];
	char liw_buf[MAX_BUF];

	memset(std_buf, 0x69, sizeof(std_buf));
	strcpy(std_buf, first);
	strncat(std_buf, second, sizeof(std_buf) - strlen(std_buf) - 1);

	memset(liw_buf, 0x69, sizeof(liw_buf));
	strcpy(liw_buf, first);
	mystrncat(liw_buf, second, sizeof(liw_buf) - strlen(liw_buf) - 1);
	
	if (memcmp(std_buf, liw_buf, sizeof(std_buf)) != 0) {
		fprintf(stderr, "liw_strncat failed, <%s> and <%s>\n",
			first, second);
		exit(EXIT_FAILURE);
	}
}

void test_ncmp(const char *first, const char *second) 
{
	size_t len;
	int std_ret, liw_ret;

	if (strlen(first) < strlen(second))
		len = strlen(second);
	else
		len = strlen(first);
	std_ret = strncmp(first, second, len);
	liw_ret = mystrncmp(first, second, len);
	if ((std_ret < 0 && liw_ret >= 0) || (std_ret > 0 && liw_ret <= 0) ||
	    (std_ret == 0 && liw_ret != 0)) {
		fprintf(stderr, "liw_strncmp failed, <%s> and <%s>\n",
			first, second);
		exit(EXIT_FAILURE);
	}
}

int main(void) 
{
	test_ncpy("");
	test_ncpy("a");
	test_ncpy("ab");
	test_ncpy("abcdefghijklmnopqrstuvwxyz");     /* longer than MAX_BUF */
	
	test_ncat("", "a");
	test_ncat("a", "bc");
	test_ncat("ab", "cde");
	test_ncat("ab", "cdefghijklmnopqrstuvwxyz"); /* longer than MAX_BUF */

	test_ncmp("", "");
	test_ncmp("", "a");
	test_ncmp("a", "a");
	test_ncmp("a", "ab");
	test_ncmp("abc", "ab");

	printf("All tests pass.\n");
	return 0;
}