C Primer Plus编程练习_第十一章(菜鸟版)

1.设计并测试一个函数,从输入中获取下n个字符(包括空白、制表符、换行符),把结果储存在一个数组里,它的地址被传递作为一个参数

// 1.子函数,从输入中获取下n个字符,结构存储在一个数组里
#include <stdio.h>
void read(char *s1, int n);

int main() {
	char ch[128] = "";//空串
	int n = 5;
	read(ch, n);
	for (int i = 0; i < n; i++) {
		printf("%c", ch[i]);
	}
	return (0);
}

void read(char *s1, int n) {
	for (int i = 0; i < n; i++) {
		s1[i] = getchar();
	}
	s1[n] = '\0';//结束标志位
	while (getchar() != '\n') {
		continue;
	}
}

2.修改并编程练习1的函数,在n个字符后停止,或在读到第1个空白、制表符或换行符时停止,哪个先遇到哪个停止。不能只使用scanf()

// 2.子函数,遇到空白、制表符、换行停止
#include <stdio.h>
#include <string.h>
void read(char *s1, int n);

int main() {
	char ch[128] = "";
	int n = 5;
	read(ch, n);
	puts(ch);
	return (0);
}

void read(char *s1, int n) {
	int i = 0;
	for (i = 0; i < n; i++) {
		s1[i] = getchar();
		if (s1[i] == '\n' || s1[i] == '\t' || s1[i] == ' ') {
			break;
		}
	}
	s1[i] = '\0';
}

3.设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。

// 3.把单词读入一个数组中,丢弃其余的字符,跳过前面的非空白
#include <stdio.h>
#include <string.h>
#include <ctype.h>

void func(char *s1) {
	char ch;
	int n = 0;
	while ((ch = getchar()) != EOF) {
		if (isalpha(ch))
			s1[n++] = ch;
	}
	s1[n] = '\0';
}

int main() {
	char s1[10];
	func(s1);
	puts(s1);
}

4.设计并测试一个函数,它类似编程练习3的描述,只不过它接受第2个参数指明可读取的最大字符数。

// 4.类似3. 但接受第二个参数n(可读取最大的字符数)
# include <stdio.h>
# include <ctype.h>
# define SIZE 128

void func(char *s1, int n) {
	int i = 0;
	char ch;
	while (i < n) {
		ch = getchar();
		if (isalpha(ch)) {
			s1[i] = ch;
			i++;
		}
		//i++;//如果可读取字符数包括非字母字符
	}
	s1[i] = '\0';
}

int main() {
	char s1[SIZE];
	func(s1, 5);
	puts(s1);
}

5.设计并测试一个函数,搜索第1个函数形参指定的字符串,在其中查找第2个函数形参指定的字符首次出现的位置。如果成功,该函数返指向该字符的指针,如果在字符串中未找到指定字符,则返回空指针(该函数的功能与 strchr()函数相同)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。

// 5.
# include <stdio.h>

char *pstr(char *s1, char ch) {
	while (*s1 != ch) {
		s1++;
	}
	return s1;
}

int main() {
	char s[10] = "abcd";
	printf("%p\n", s);
	printf("%p\n", pstr(s, 'c'));
}

6.编写一个名为is_within()的函数,接受一个字符和一个指向字符串的指针作为两个函数形参。如果指定字符在字符串中,该函数返回一个非零值(即为真)。否则,返回0(即为假)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值 。

// 6.判断字符在不在字符串中
# include <stdio.h>
# include <stdbool.h>
# include <string.h>

bool is_within(char ch, char *s1) {
	bool flag = false;
	while (*s1) {
		if (*s1 == ch) {
			flag = true;
			break;
		}
		s1++;
	}
	return (flag);
}

int main() {
	int i = 0;
	char str[128];
	char ch1, ch2;	// ch2是给str使用的
	bool flag;
	// input with loop
	printf("char:");
	scanf("%c", &ch1);
	printf("str:");
	while (getchar() == '\n')
		continue;
	while ((ch2 = getchar()) != '\n') {
		str[i++] = ch2;
	}
	str[i] = '\0';

	// address
	flag = is_within(ch1, str);
	if (flag)
		printf("char in str");
	else
		printf("char not in it");
	return (0);
}

7.strncpy(s1, s2, n)函数把s2中的n个字符拷贝至s1中,截断s2,或者有必要的话在末尾添加空字符。如果s2的长度是n或多于n,目标字符串不能以空字符结尾。该函数返回s1。自己编写一个这样的函数,名为mystrncpy()。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。

// 7.自己写一个strncpy(s1,s2,n)
# include <stdio.h>
# include <string.h>

char *mystrncpy(char *s1, char *s2, int n) {
	int i = 0;
	while (i < n) {
		s1[i] = s2[i];
		i++;
	}
	s1[i] = '\0';
	return s1;
}

int main() {
	char str1[128], str2[128] = "abcdefg";
	char *pstr;
	pstr = mystrncpy(str1, str2, 10);
	while (*pstr != '\0')
		printf("%c", *pstr++);
}

8.编写一个名为string_in()的函数,接受两个指向字符串的指针作为参数。如果第2个字符串中包含第1个字符串,该函数将返回第1个字符串开始的地址。

// 8.字符串包含字符串
#include <stdio.h>
#include <string.h>

char *pstr(char *pstr1, char *pstr2) {
	//判断str1在不在str2里面
	int i1 = 0, i2 = 0;
	char *pstr = NULL;	// 返回的指针
	while (pstr2[i2]) {
		i1 = 0;
		while ((pstr2[i2] == pstr1[i1]) && pstr1[i1]) {
			i2++;
			i1++;
		}
		if (i1 == strlen(pstr1)) {
			pstr = &pstr2[i2 - i1];
			break;
		}
		i2++;
	}
	return pstr;
}

int main() {
	char str1[10] = "abc";
	char str2[10] = "abeeabc";
	printf("str2:%p\n", str2);
	printf("str1 in str2:%p\n", pstr(str1, str2));
	return (0);
}

9.编写一个函数,把字符串中的内容用其反序字符串代替。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。

// 9.字符串内容反序代替
# include <stdio.h>
# include <string.h>

void rev(char s[]) {
	int len = strlen(s);
	char temp;
	for (int i = 0; i < len / 2; i++) {
		temp = s[i];
		s[i] = s[len - 1 - i ];
		s[len - 1 - i ] = temp;
	}
}

int main() {
	char str[10] = "abcd";
	rev(str);
	puts(str);
}

10.编写一个函数接受一个字符串作为参数,并删除字符串中的空格。在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。该程序应该应用该函数读取每个输入的字符串,并显示处理后的字符串。

// 10.接受一个字符串为参数,删除字符串中的空格。
// 循环输入行,直到用户输入一行空行。
# include <stdio.h>

void func(char *s) {
	int j, i = 0;
	while (s[i] != '\0') {
		if (' ' == s[i]) {
			for (j = i; s[j + 1] != '\0'; j++) 	// 前移
				s[j] = s[j + 1];
			s[j] = '\0';
			i--;
		}
		i++;
	}
}

int main() {
	char s[128] = "";
	while (1) {
		printf("str:");
		gets(s);
		if (!*s)
			break;
		printf("new str:");
		func(s);
		puts(s);

	}
	printf("Done.");
	return (0);
}

11.编写一个函数,读入10个字符串或者读到EOF时停止。该程序为用户提供一个有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按长度递增顺序打印字符串、按字符串中第1个单词的长度打印字符串、退出。菜单可以循环显示,除非用户选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。

// 11.读入10个字符串或者EOF停止,字符串排序
//引用区===================================
#include <stdio.h>
#include <string.h>	//strlen()
#include <ctype.h>	//isalpha()
#include <stdlib.h>	//exit(0)
//宏定义===================================
# define LIM 5
# define SIZE 81

//子函数===================================
char *s_gets(char *str, int n) {
	char *ret_val;
	int i = 0;

	ret_val = fgets(str, n, stdin);			//输入
	if (ret_val) {							//字符串非空
		while (str[i]
		        != '\n' && str[i] != '\0')	//找到换行符
			i++;
		if (str[i] == '\n')
			str[i] = '\0';						//换行符改休止
		else
			while (getchar() != '\n')			//遇到休止换行继续输入
				continue;
	}
	return ret_val;
}

void original(char *str[], int num) {
	/*原样打印*/
	for (int i = 0; i < num; i++) {
		puts(str[i]);
	}
}

void ascii(char *str[], int num) {
	/*ASCII打印*/
	char *temp;
	for (int top = 0; top < num - 1; top++)
		for (int seek = top + 1; seek < num; seek++)
			if (strcmp(str[top], str[seek]) > 0) {
				temp = str[top];
				str[top] = str[seek];
				str[seek] = temp;
			}
	for (int i = 0; i < num; i++) {
		puts(str[i]);
	}
}

void length(char *str[], int num) {
	/*长度打印*/
	char *temp;
	for (int top = 0; top < num - 1; top++)
		for (int seek = top + 1; seek < num; seek++)
			if (strlen(str[top]) < strlen(str[seek])) {
				temp = str[top];
				str[top] = str[seek];
				str[seek] = temp;
			}
	for (int i = 0; i < num; i++) {
		puts(str[i]);
	}
}

void first_word_length(char *str[], int num) {
	/*第一个单词长度,降序*/
	/*同索引第一个遇到空格就是短单词*/
	char *temp;
	int i = 0;
	for (int top = 0; top < num - 1; top++)
		for (int seek = top + 1; seek < num; seek++) {
			i = 0;
			while (isalpha(str[top][i]) || isalpha(str[seek][i])) { //至少一个字母
				if (str[top][i] == '\0' && str[seek][i] != '\0') { //top方休止,交换后循环退出
					temp = str[top];
					str[top] = str[seek];
					str[seek] = temp;
					break;
				} else if ((!isalpha(str[top][i]) && isalpha(str[seek][i]))) { //top方非字母
					temp = str[top];
					str[top] = str[seek];
					str[seek] = temp;
					break;
				} else if (!isalpha(str[seek][i]) || str[seek][i] == '\0') { //seek方休止或非字母
					break;
				}
				i++;
			}
		}

	for (int i = 0; i < num; i++) {
		puts(str[i]);
	}
}


//主程序===================================
int main() {
	char s[LIM][SIZE];	//地址不是变量
	char *pstr[LIM];	//元素是变量
	int choice, ct = 0;
	char *choices[5] = {
		"1.Original",
		"2.Ascii",
		"3.Length",
		"4.First word length",
		"5.QUIT"
	};

	while (ct < LIM && s_gets(s[ct], SIZE) && s[ct][0] != '\0') {
		pstr[ct] = s[ct];
		ct++;
	}
	printf("pls choose one way:");
	scanf("%d", &choice);
	while (choice != 5) {
		puts("==========================");

		switch (choice) {
			case (1):
				puts("you choose the first way:");
				original(pstr, LIM);
				puts("==========================");
				break;
			case (2):
				puts("you choose the second way:");
				ascii(pstr, LIM);
				puts("==========================");
				break;
			case (3):
				puts("you choose the third way:");
				length(pstr, LIM);
				puts("==========================");
				break;
			case (4):
				puts("you choose the fourth way:");
				first_word_length(pstr, LIM);
				puts("==========================");
				break;
		}
		printf("pls choose one way again:");
		scanf("%d", &choice);
	}
	printf("Done.");

	return (0);
}

12.编写一个程序,读取输入,直至读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h头文件中的函数

// 12.报告读入字符数
# include <stdio.h>
# include <ctype.h>
# include <stdbool.h>

int main() {
	char ch;
	bool flag = false;
	int word = 0, upper = 0, lower = 0, punct = 0, num = 0;
	while ((ch = getchar()) != EOF) {
		if (isalpha(ch))
			if (flag == false) {
				word++;
				flag = true;
			}
		if (isupper(ch))
			upper++;
		else if (islower(ch))
			lower++;
		else if (ispunct(ch)) {
			punct++;
			flag = false;
		} else if (isdigit(ch)) {
			num++;
			flag = false;
		} else
			flag = false;

	}
	printf("WORD:%d\nUPPER:%d\nLOWER:%d\nPUNCT:%d\nNUM:%d\n",
	       word, upper, lower, punct, num);
	return (0);
}

13.编写一个程序,反序显示命令行参数的单词。例如,命令行参数是 see you later,该程序应打印later you see。

// 13.反序打印命令行参数
#include <stdio.h>

int main(int argc, char *argv[]) {
	for (int i = 1; i < argc; i++) {
		printf("%s\t", argv[argc - i]);
	}
	return (0);
}

14.编写一个通过命令行运行的程序计算幂。第1个命令行参数是double类型的数,作为幂的底数,第2个参数是整数,作为幂的指数

// 14.命令行参数,第一个是double类型的幂底数,第二个是int类型的指数
#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[]) {
	double x, result;
	int y;
	x = atof(argv[1]) ;
	y = atoi(argv[2]);
	result = pow(x, y);
	printf("x^y=%.2lf", result);
	return (0);
}

15.使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字,该函数返回0

// 15.写atoi()函数
# include <stdio.h>

int digit(char *s) {
	int num = 0;
	while (*s != '\0') {
		num = 10 * num + (*s - '0');
		s++;
	}
	return (num);
}

int main() {
	printf("%d", digit("123"));
	return (0);
}

16.编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出来。该程序识别和实现下面的命令行参数

// 16.识别命令行参数实现特定功能
//引用区=========================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//主程序=========================
int main(int argc, char *argv[]) {
	FILE *fp;
	char *filename = argv[1];
	char *model = argv[2];
	char line[128];	//行缓冲
	if (!(fp = fopen(filename, "r"))) {
		printf("ERRO OPENNING!!");
		exit(1);
	}
	//先读取
	fgets(line, 128, fp);
	while (!feof(fp)) {	//遇到EOF停止
		if ("-p" == model)	//"-p"原样打印
			fputs(line, stdout);
		else if ("-u" == model) //"-u"大写打印
			fputs(strupr(line), stdout);
		else if ("-l" == model) //"-l"小写打印
			fputs(strlwr(line), stdout);

		fgets(line, 128, fp);	//再次读取
	}
	fclose(fp);
	return (0);
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值