C primer plus课后习题答案(部分)

  6.strncpy (sl,s2,n)函数从s2复制n个字符给sl,并在必要时截断s2或为其填充额外的空字符。如果s2的长度等于或大于n,目标字符串就没有标志结束的 空字符。函数返回sl。自己编写这个函数,并在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include<stdio.h>
#include<string.h>
char *strncpy(char *s1, char *s2, int n);
int main(void)
{
char a1[81], a2[81];
int n;
do
{
puts("Please input a string");
gets(a2);
puts("PLease input number n");
scanf("%d", &n);
getchar();
puts(strncpy(a1, a2, n));

} while (*a2 != 'q');
puts("quit");
getchar();
return 0;
}
char *strncpy(char *s1, char *s2, int n)
{
int i;
for (i = 0; i < n; i++)
{
*(s1+i) = *(s2+i);
}
if (strlen(s2) >= n)
*(s1 + i) = '\0';
return s1;
}
8.7修改第七章的联系8,使菜单选项有字符代替数字进行标记。
#include<stdio.h>
#include<stdlib.h>
#define A 1.5
void hand(void);
int main(void)
{
double wages, taxs, netpay,hour;
int ch;
hand();
printf("Please input your grades,suah as a,b,c,d\n");
while (((ch = getchar()) <= 'a' || (ch = getchar()) >= 'd') && (ch = getchar()) != 'q')
{
printf("Please input your hour every weeks\n");
if (scanf("%lf", &hour) != 1)
{
printf("Please input interger number!\n");
// exit(1);//终止程序
}
if (hour <= 40)
{
if (ch == 'a')
wages = 8.75*hour;
else if (ch == 'b')
wages = 9.33*hour;
else if (ch == 'c')
wages = 10.00*hour;
else if (ch == 'd')
wages = 11.20*hour;
else
printf("I understand only a,b,c,d,q\n");
}
if (hour>40)
{
if (ch == 'a')
wages = 8.75 * 40 + 8.75*(hour - 40)*A;
else if (ch == 'b')
wages = 9.33*40+9.33*(hour-40)*A;
else if (ch == 'c')
wages = 10.00*40+10.00*(hour-40)*A;
else if (ch == 'd')
wages = 11.20*40+11.20*(hour-40)*A;
else
{
printf("I understand only a,b,c,d,q\n");
break;
}
}
if (wages <= 300)
{
taxs = 0.15*wages;
}
else if (wages <= 450)
{
taxs = 0.15 * 300 + (wages - 300)*0.2;
}
else
taxs = 0.15 * 300 + 150 * 0.2 + 0.25*(wages - 450);
while (getchar() != '\n')
;
printf("wages=%.4lf\ntaxs=%.4lf\nnetpay=%.4lf\n", wages, taxs, wages - taxs);
printf("Please input your grades,suah as a,b,c,d\n");

}
getchar();
return 0;
}
void hand(void)
{
int i;
for (i = 0; i < 64; i++)
printf("*");
putchar('\n');
printf("Enter the number corresponding to the desired pay rate or actoin\n ");
printf(")$8.75/hr                    b)$9.33/hr\n");
printf("c)$10.00/hr                   d)$11.20/hr\n");
for (i = 0; i < 64; i++)
printf("*");
putchar('\n');
}
需要注意回车键的处理,类似的问题基本上都可以用while(getchar()!=‘\n’);
来处理!
#include<stdio.h>
#include<ctype.h>
char get_first(void);

//b.加班
#define TIME 40  //加班(超过TIME小时) =
#define ADD  1.5  //ADD倍的时间
//c.税率
#define LIMIT1 300  //前LIMIT1美元为RATE1
#define RATE1 0.15 
#define LIMIT2 150  //下一个LIMIT2美元为RATE2
#define RATE2 0.20
#define RATE3 0.25 //余下的位RATE3

int main(void)
{
double basic, hours, gross, tax;
printf("Enter the number corresponding to the desired pay rate or action:\n");
printf("a) $8.75/hr\t\t\tb) $9.33/hr\n");
printf("c) $10.00/hr\t\t\td) $11.20/hr\n");
printf("q) quit\n");
switch (get_first())
{
case 1: basic = 8.75; break;
case 2: basic = 9.33; break;
case 3: basic = 10.00; break;
case 4: basic = 11.20; break;
default: printf("quit\n"); return(0); //退出程序
}
printf("you have select $%.2lf\n", basic);
printf("input the work hours of a week:");
scanf("%lf", &hours);
if (hours > 40) hours = 40 + (hours - 40) * 1.5;
gross = hours * basic;
printf("gross income:\t\t%lf\n", gross);
if (gross <= LIMIT1) tax = gross * RATE1;
else if (gross <= LIMIT2) tax = LIMIT1 * RATE1 + (gross - LIMIT1) * RATE2;
else tax = LIMIT1 * RATE1 + LIMIT2 * RATE2 + (gross - LIMIT1 - LIMIT2) * RATE3;
printf("tax:\t\t\t%lf\n", tax);
printf("net income:\t\t%lf\n", gross - tax);
getchar();
getchar();
return(0);
}

char get_first(void) //得到字符串中的第一个非空字符
{
int ch;
while (isspace(ch = getchar()));
while (getchar() != '\n');
return ch-96;
}对比这个就知道自己写的有多烂了
8. 编写一个程序,显示一个菜单,为您提供加法、减法、乘法或除法的选项。获得您的选择后,该程序请求两个数,然后执行您选择的操作。该程序应该只接受它所提 供的菜单选项。它应该使用float类型的数,并且如果用户未能输入数字应允许其重新输入。在除法的情况中,如果用户输入0作为第二个数,该程序应该提示 用户输入一个新的值。一个典型的程序运行应该如下所示:
#include<stdio.h>
#include<ctype.h>
char asmd(void);
float get_float(void);
int main(void)
{
float first, second;
char ch;
printf("Enter the operation of your choice:\n");
printf("a.add\t\t\ts.subtract\n");
printf("m.multiply\t\td.divide\n");
printf("q.quit\n");
while ((ch = asmd())!= 'q')
{
printf("Please input the first number: ");
first = get_float();
printf("Please input the second number: ");
second = get_float();
switch (ch)
{
case 'a':
printf("%f+%f=%f\n", first, second, first + second);
break;
case 's':
printf("%.4f-%.4f=%.4f\n", first, second, first - second);
break;
case 'm':
printf("%.4f*%.4f=%.4f\n", first, second, first*second);
break;
case 'd':
{
if (second == 0)
{
printf("Enter a number other than 0: ");
second = get_float();
}
printf("%.4f/%.4f=%.4f\n", first, second, first / second);
}break;
default:
printf("I understand only a,s,m,d\n");
}
printf("Enter the operation of your choice:\n");
printf("a.add\t\t\ts.subtract\n");
printf("m.multiply\t\td.divide\n");
printf("q.quit\n");
}
//getchar();
getchar();
return 0;

}
char asmd(void)
{
int ch;
while (isspace(ch = getchar()))
continue;
while (getchar() != '\n');
return ch;
}
float get_float(void)
{
float num;
char ch;
while (scanf("%f", &num)!= 1)
{
while ((ch = getchar()) != '\n')
putchar(ch);
printf(" is not an integer.\nPlease input an integer,such as 2.5,-1.7E8,or3:1  ");
}
return num;
}重点和关键还是在回车键的处理,另外模块化编程有很多好处,比如避免重复代码等,本题中的开始菜单也可以写在函数中比较好


11.1.设计并测试一个函数,可以从输入读取n个字符(包括空格、制表符和换行符),把结果存储在一个数组中,这个数组的地址通过参数来传递。
#include<stdio.h>
void input(int n, char *ptr);
int main(void)
{
int n;
char arry[81];
printf("Please input the number of strings\n");
scanf("%d", &n);
getchar();//消除回车
puts("input your strings");
input(n, arry);
puts(arry);
getchar();
getchar();
return 0;
}
void input(int n, char *ptr)
{
int i;
for (i = 0; i < n; i++)
*(ptr + i) = getchar();
*(ptr + i) = '\0';
}要注意在数组结尾添加空字符'\0'来结束数组指针//数组指针仍还是理解难点


2.修改并测试练习1中的函数,使得可以在n个字符后,或第一个空格、制表符、换行符后停止读取输入,由上述情况中最先被满足的那个终止读取(不能用scanf()函数)。
#include<stdio.h>
#include<ctype.h>
void input(int n, char *ptr);
int main(void)
{
int n;
char arry[81];
printf("Please input the number of strings\n");
scanf("%d", &n);
getchar();//消除回车
puts("input your strings");
input(n, arry);
puts(arry);
getchar();
getchar();
return 0;
}
void input(int n, char *ptr)
{
int i;
for (i = 0; i < n; i++)
{
*(ptr + i) = getchar();
if (isspace(*(ptr + i)))
*(ptr + i) = '\0';
}
*(ptr + i) = '\0';
}
这是我所想到的方法,还有一种这样的也还不错!
#include<stdio.h>
#include<ctype.h>
void input(int n, char *ptr);
int main(void)
{
int n;
char arry[81];
printf("Please input the number of strings\n");
scanf("%d", &n);
getchar();//消除回车
puts("input your strings");
input(n, arry);
puts(arry);
getchar();
getchar();
return 0;
}
void input(int n, char *ptr)
{
int i;
for (i = 0; i < n; i++)
{
*(ptr + i) = getchar();
if (isspace(*(ptr + i)))
break;
}
*(ptr + i) = '\0';
}


 3.设计并测试一个函数,其功能是读取输入行里的第一个单词到数组,并丢掉该行中其他的字符。一个单词的定义是一串字符,其中不含空格、制表符和换行符。
#include<stdio.h>
#include<ctype.h>
void p_word(char *ptr);
int main(void)
{
char a[81];
puts("Please input the strings");
gets(a);
puts("input the strings");
puts(a);
p_word(a);
puts("output the strings");
puts(a);
getchar();
return 0;
}
void p_word(char *ptr)
{
int begin, end;
for (begin = 0; isspace(*(ptr + begin)); begin++)
{
if (*(ptr + begin) == '\0')//这个循环主要是处理输入的一行字符中前面的都是空白符
break;
}
for (end = begin; !isspace(*(ptr + end)); end++)
{
if (*(ptr + end) == '\0')
break;//这两行的作用是防止如果一行字符没有空白符时,发生的溢出导致的错误
}
*(ptr + end) = '\0';
for (; *(ptr + begin) != '\0'; ptr++)
*ptr = *(ptr + begin);
*ptr = '\0';


}



4.设计并测试一个函数,其功能是搜索由函数的第一个参数指定的字符串,在其中查找由函数的第二个参数指定的字符的第一次出现的位置。如果找到,返回指向 这个字符的指针:如果没有找到,返回空字符(这种方式和strchr()函数的功能一样)。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。




#include<stdio.h>
char * i_strchr( char *ptr, char ch);
int main(void)
{
char a[81],ch,*p;
puts("Please input the strings");
do
{
gets(a);
puts("Pleae input a char to search");
ch = getchar();
getchar();
p = i_strchr(a, ch);
if (p)
{
puts("Find!");
puts(p);
}
else
puts("Can't find");
puts("Please input any strings expect q to go on");
} while (*a != 'q');
puts("quit");
getchar();
return 0;

}
char * i_strchr( char *ptr, char ch)
{
int i;
if (*ptr == '\0')
return NULL;
else
{
while (*ptr)

{

if (*ptr == ch)

return ptr;
++ptr;

}
return NULL;
}
}

 5.编写一个函数is_witlun()。它接受两个参数,一个是字符,另一个是字符串指针。其功能是如果字符在字符串中,就返回一个非O值(真);如果字符不在字符串中,就返回O值(假)。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include<stdio.h>
int is_within(char ch, char *ptr);
int main(void)
{
char ch, a[81];
do
{
puts("Please input a char");
ch = getchar();
getchar();
puts("PLease input a strings expect q");
gets(a);
if (is_within(ch, a))
puts("Find!");
else
printf("sorry,Can't find %c\n", ch);

} while (*a != 'q');
puts("quit");
getchar();
return 0;
}
int is_within(char ch, char *ptr)
{
if (*ptr == '\0')
return 0;
while (*ptr)
{
if (*ptr == ch)
return 1;
++ptr;
}
if (*ptr == '\0')
return 0;
}
  6.strncpy (sl,s2,n)函数从s2复制n个字符给sl,并在必要时截断s2或为其填充额外的空字符。如果s2的长度等于或大于n,目标字符串就没有标志结束的 空字符。函数返回sl。自己编写这个函数,并在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include<stdio.h>
char * strncpy(char *s1, char *s2, int n);
int main(void)
{
int n;
char a[81], b[81];
do
{
puts("Pleae input a number of length of a[]");
scanf("%d", &n);
getchar();
puts("Please input a strings of b[] expect 'q'");
gets(b);
// getchar();
puts("output strings a[]");
puts(strncpy(a, b, n));
} while (*b != 'q');
puts("quit");
getchar();
return 0;
}
char * strncpy(char *s1, char *s2, int n)
{
int i;
for (i = 0; i < n; i++)
{
*(s1 + i) = *(s2 + i);
if (*(s2 + i)=='\0')
break;//这两行可省略
}
if (*(s2 + i) != '\0')
*(s1 + i) = '\0';
return s1;
}
   7.编写一个函数string_in(),它接受两个字符串指针参数。如果第二个字符串被包含在第一个字符串中,函数就返回被包含的字符开始的地址。例 如,string_in("hats","at")返回hats中a的地址,则,函数返回空指针。在一个使用循环语句为这个函数提供输入的完整程序中进行 测试。
  8.编写一个函数,其功能是使输入字符串反序。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。

#include<stdio.h>
#include<string.h>
char *output(char *ptr,char *ptr2);
int main(void)
{
char a[81],b[81];
do
{
puts("Please input a[] strings expect 'q'");
gets(a);
puts("output a[]");
puts(output(a,b));
} while (*a != 'q');
puts("quit");
getchar();
return 0;
}
char *output(char *ptr,char *ptr2)
{
char *ptr2;
int i,j;
j = strlen(ptr);
for (i = 0; i <=j; i++)
{
*(ptr2 + i) = *(ptr - j + i);
}
*(ptr2 + j) = '\0';
return ptr2;

}
  9.编写一个函数。其参数为一个字符串,函数删除字符串中的空格。在一个可以循环读取的程序中进行测试,直到用户输入空行。对于任何输入字符串,函数都应该适用并可以显示结果。
#include<stdio.h>
char *despace(char *ptr,char *ptr2);
int main(void)
{
char a[81],b[81];
do
{
puts("Please input a[] string");
gets(a);
puts("output new a[]");
puts(despace(a,b));
} while (*a != '\r');
puts("quit");
getchar();
return 0;
}
char *despace(char *ptr,char *ptr2)
{
int i, j = 0;
for (i = 0; *(ptr + i) != '\0'; i++)
{
if(*(ptr + i) != ' ')
{
*(ptr2 + j) = *(ptr + i);
j++;
}
}
*(ptr2 + j) = '\0';
return ptr2;
}
10.编写一个程序,读取输入,直到读入了10个字符串或遇到EOF,由二者中最先被满足的那个终止读取过程。这个程序可以为用户提供一个有5个选项的菜 单:输出初始字符串列表、按ASCII顺序输出字符串、按长度递增顺序输出字符串、按字符串中第一个单词的长度输出字符串和退出。菜单可以循环,直到用户 输入退出请求。当然,程序要能真正完成菜单中的各项功能。
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void pf_string(int n,char *ptr[]);
void pf3_string(int n, char *ptr[]);
void pf4_string(int n, char *ptr[]);
int main(void)
{
int i,n,j;
char a[10][81],*ptr[10];
puts("Please input a string");
for (i = 0; i < 10 && gets(a[i]) != NULL; i++)//没有初始化
{
ptr[i] = a[i];//令指针指向输入字符串
}
puts("Please input a number of 1-5 to choose the way output");
puts("Case 1 In the initial order output");
puts("Case 2 In the ASCII order output");
puts("Case 3 In the lenght order output");
puts("Case 4 In the length increasing order output");
puts("Case 5 In the first word lenght order output");
printf("Please input a number of Case:");
while (scanf("%d", &n) == 1)
{
switch (n)
{
case 1:
for (i = 0; i < 10; i++)
puts(ptr[i]);
break;
case 2:
pf_string(i, ptr);
for (i = 0; i < 10; i++)
puts(ptr[i]);
break;
case 3:
pf3_string(i, ptr);
for (i = 0; i < 10; i++)
puts(ptr[i]);
break;
case 4:
pf4_string(i, ptr);
for (i = 0; i < 10; i++)
puts(ptr[i]);
break;
case 5:
return 0;
break;
default:
puts("sorry!I can understand only 1-5");
}
}
getchar();
getchar();
return 0;

}
void pf_string(int n, char *ptr[])
{
char *temp;
int top, seek;

for (top = 0; top < n - 1; top++)
for (seek = top + 1; seek < n; seek++)
{
if (strcmp(ptr[top], ptr[seek])>0)
{
temp = ptr[top];
ptr[top] = ptr[seek];
ptr[seek] = temp;
}

}
}
void pf3_string(int n, char *ptr[])
{
char *temp;
int top, seek;

for (top = 0; top < n - 1; top++)
for (seek = top + 1; seek < n; seek++)
{
if (strlen(ptr[top])>strlen(ptr[seek]))
{
temp = ptr[top];
ptr[top] = ptr[seek];
ptr[seek] = temp;
}
}
}
void pf4_string(int n, char *ptr[])
{
char *temp;
int top, seek;
for (top = 0; top < n; top++)
for (seek = 0; ptr[top][seek] != '\0'; seek++)
if (isspace(ptr[top][seek]))
ptr[top][seek] = '\0';
for (top = 0; top < n - 1; top++)
for (seek = top + 1; seek < n; seek++)
{
if (strlen(ptr[top])>strlen(ptr[seek]))
{
temp = ptr[top];
ptr[top] = ptr[seek];
ptr[seek] = temp;
}
}
}
  11.编写一个程序。功能是读取输入,直到遇到EOF,并报告单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h系列的函数。
#include<stdio.h>
#include<ctype.h>
int main(void)
{
int a[81];
int i, j = 0;;
for (i = 0; (a[i] = getchar()) != EOF; i++)
;
a[i] = '\0';
for (i = 0; a[i] != '\0';i++)
if (isupper(a[i]))
j++;
printf("The number of upper is %d\n", j);
for (i = 0,j=0; a[i] != '\0'; i++)
if (islower(a[i]))
j++;
printf("The number of lower is %d\n", j);
for (i = 0, j = 0; a[i] != '\0'; i++)
if (ispunct(a[i]))
j++;
printf("The number of punct is %d\n", j);
for (i = 0, j = 0; a[i] != '\0'; i++)
if (isdigit(a[i]))
j++;
printf("The number of digit is %d\n", j);
for (i = 0, j = 0; a[i] != '\0'; i++)
if (a[i] != '\n')
if (isspace(a[i])||ispunct(a[i]))
j++;
printf("The number of word is %d\n", j);
getchar();
return 0;

}
    13.编写一个计算乘幂的基于命令行的程序。第一个命令行参数为double类型数,作为幂的底数;第二个参数为整数,作为幂的指数。
#include<stdio.h>
int main(void)
{
double a,a_n=1;
int n,i;
puts("Pleasae input the di of a");
while (scanf("%lf", &a)==1)
{
puts("Please input the mi of n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
a_n = a_n*a;
printf("the a of n is %.4lf\n", a_n);
a_n = 1;//注意要初始化
puts("Pleasae input the di of a");
}
getchar();
getchar();
return 0;
}

14.使用字符分类函数实现atoi()函数。
#include<stdio.h>
#include<ctype.h>
char * i_atoi(char *ptr,char *ptr2);
int main(void)
{
char a[81],b[81];
puts("Please input a strings");
gets(a);
puts(i_atoi(a,b));
getchar();
return 0;
}
char * i_atoi(char *ptr,char *ptr2)
{
int i,j=0;
for (i = 0; *(ptr+i)!= '\0'; i++)
if (isdigit(*(ptr + i)))
{
*(ptr2+j) = *(ptr + i);
j++;
}
*(ptr2 + j) = '\0';
return ptr2;

}

 15,编写一个程序,其功能是读取输入,直到遇到文件结尾,并把文件显示出来。要求程序可以识别并执行下面的命令行参数:
#include<stdio.h>
#include<ctype.h>
int main(void)
{
char a[81],b[5];
int i;
puts("Please input a char to choose the ways output");
puts("input '-p'to initial order output");
puts("input '-u'to upper order output");
puts("input '-1'to lower order output");
gets(b);
puts("Please input a string of a[]");
for (i = 0; (a[i] = getchar()) != EOF; i++)
{
switch (b[1])
{
case 'p':
printf("%c", a[i]);
break;
case 'u':
toupper(a[i]);
printf("%c", toupper(a[i]));
break;
case '1':
printf("%c", tolower(a[i]));
break;
default:
puts("sorry ,I can only understand '-1','-p','-u'");
gets(b);
}
}
getchar();
return 0;
}


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值