C Primer Plus(第六版)第十一章 编程练习答案
Posted 水番正文
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C Primer Plus(第六版)第十一章 编程练习答案相关的知识,希望对你有一定的参考价值。
前言:这次感觉融起来了,各章的知识都有用到,不过这次时间隔的是够久的。
仅供参考,新手勿喷。
CH11 Code answer 1:
#include <stdio.h>
#define SIZE 100
void s_gots(char *);
int main(void)
{
char str[SIZE];
printf("Enter your string(enter q to quit):");
s_gots(str);
printf("REVIEW:%s",str);
return 0;
}
void s_gots(char * str)
{
// char str[SIZE]; 这是局部变量的地址 当用这个地址返回 这个函数的栈帧已经被销毁
// 虽然数据可能还在 但行为未定义 所以要传递参数
int i = 0;
while( str[i] = getchar() )
{
if(str[i] == 'q')
break;
i++;
}
printf("%p\\n",str); //如果是局部变量虽然地址一样 但内容应该已经被覆盖
}
CH11 Code answer 2:
#include <stdio.h>
#define SIZE 100
void s_gots(char *);
int main(void)
{
char str[SIZE];
printf("Enter your string(enter space or tab or enter or max character num to quit):");
s_gots(str);
printf("REVIEW:%s",str);
return 0;
}
void s_gots(char * str)
{
// char str[SIZE]; 这是局部变量的地址 当用这个地址返回 这个函数的栈帧已经被销毁
// 虽然数据可能还在 但行为未定义 所以要传递参数
int i = 0;
while( str[i] = getchar() )
{
if(str[i] == '\\n' || str[i] == '\\t' || str[i] == ' ' || i == SIZE-2) //在98的时候退出
{
// str[i] = '\\0'; //当字符到str[99]这个字符默认为'/0' 不能改变因为是最后一个字符
break;
}
i++;
}
printf("%p\\n",str); //如果是局部变量虽然地址一样 但内容应该已经被覆盖
}
CH11 Code answer 3:
#include <stdio.h>
#include <ctype.h>
#define SIZE 20
void s_got(char *);
int main(void)
{
char str[SIZE];
printf("Enter your character(enter other character to quit):");
s_got(str);
printf("The character is '%s'",str);
return 0;
}
void s_got(char * str)
{
int i = 0;
int ch;
while( !isalpha(ch = getchar()) ) //去除缓冲区的空格
continue; //当不成立时 说明第一个字符已经从缓冲区传送到ch中
str[i++] = ch;
while( isalpha(ch = getchar()) ) //为什么当结尾不成立时还是会赋值??
str[i++] = ch;
str[i] = '\\0'; //这条设置了最后一个字符是\\0
//但如果最后不成立一个字符成功 那么这个i应该不成立字符之后??
}
CH11 Code answer 4:
#include <stdio.h>
#include <ctype.h>
#define SIZE 10
void s_got(char *,int);
int main(void)
{
char str[SIZE];
printf("Enter your character(enter other character or max character num to quit):");
s_got(str,SIZE); //要确保数组元素比字符多一
printf("The character is '%s'",str);
return 0;
}
void s_got(char * str,int n)
{
int i = 0;
int ch;
while( !isalpha(ch = getchar()) ) //去除缓冲区的空格
continue;
do
{
str[i++] = ch;
}while( isalpha(ch = getchar()) && i < n-1); //空出一字节放'\\0' 也就是最多0 ~ 8
}
CH11 Code answer 5:
#include <stdio.h>
#include <string.h>
#define SIZE 40
char * s_strchr(char *,char);
int main(void)
{
char str[SIZE];
char ch;
char * pt;
while(pt)
{
printf("Please enter the string(error to quit):");
scanf("%s",str);
while(getchar() != '\\n')
continue;
printf("Please enter the search string:");
scanf("%c",&ch);
pt = s_strchr(str,ch);
printf("The localtion of first is '%s'\\n\\n",pt);
}
return 0;
}
char * s_strchr(char * str, char ch)
{
int i = 0;
while(i < strlen(str))
{
if( str[i] == ch )
return &str[i];
i++;
}
return NULL;
}
CH11 Code answer 6:
#include <stdio.h>
#include <string.h>
#define SIZE 40
int s_strchr(char *,char);
int main(void)
{
char str[SIZE];
int pt = 1;
char ch;
while(pt)
{
printf("Please enter the string(error to quit):");
scanf("%s",str);
while(getchar() != '\\n')
continue;
printf("Please enter the search string:");
scanf("%c",&ch);
pt = s_strchr(str,ch);
printf("The localtion of first is '%d'\\n\\n",pt);
}
return 0;
}
int s_strchr(char * str, char ch)
{
int i = 0;
while(i < strlen(str))
{
if( str[i] == ch )
return 1;
i++;
}
return 0;
}
CH11 Code answer 7:
#include <stdio.h>
#include <string.h>
#define SIZE 10
char * MyStrncpy(char *, char *, int);
int main(void)
{
char str1[SIZE] = "012345678"; //共十个元素最多九个字符 0~8
char str2[SIZE+SIZE];
char ch = '@';
while(strncmp(str1,&ch,1))
{
printf("Please enter the copy string(enter @ to quit):");
scanf("%s",str2);
while(getchar() != '\\n')
continue;
printf("The localtion of first is '%s'\\n\\n",MyStrncpy(str1,str2,SIZE));
}
return 0;
}
char * MyStrncpy(char * str1, char * str2, int n)
{
int i;
for(i = 0; i < n-1; i++) //0~8 最后9默认填充\\0
str1[i] = str2[i];
return str1;
// strncpy(str1, str2, n-1); //最多九个字符 也就是0~8
// str1[n-1] = '\\0'; //最后一个字符也就是str1[9]存储结束符
}
CH11 Code answer 8:
#include <stdio.h>
#include <string.h>
#define SIZE 10
char * string_in(char *, char *);
int main(void)
{
char str1[SIZE];
char str2[SIZE];
char * pt;
while(pt)
{
printf("Please enter the first string(error to quit):");
scanf("%s",str1);
while(getchar() != '\\n')
continue;
printf("Please enter the search string:");
scanf("%s",&str2);
while(getchar() != '\\n')
continue;
pt = string_in(str1,str2);
printf("The localtion of first is '%s'\\n\\n",pt);
}
return 0;
}
char * string_in(char * str1, char * str2)
{
int i = 0;
int j;
while( i < strlen(str1))
{
if( str2[0] == str1[i] ) //查找第一个字符
{
for(j = 1; j < strlen(str2); j++)
{
if( str2[j] != str1[i+j] ) //遍历接下里的字符是否符合
break;
}
if( strlen(str2) == j ) //当所有符合j会运行到最后没有退出 j相等于str2长度
return &str1[i];
}
i++;
}
return NULL;
}
CH11 Code answer 9:
#include <stdio.h>
#include <string.h>
#define SIZE 10
void Reverse(char *);
int main(void)
{
char str1[SIZE];
char ch = '@';
while( strncmp(str1, &ch, 1) )
{
printf("Enter some need to reverse string(enter @ to quit):");
scanf("%s",str1);
Reverse(str1);
printf("The Reverse string is '%s'\\n\\n", str1);
}
return 0;
}
void Reverse(char * str)
{
int i,b;
char pz;
//像这个要思考的是什么!? 两个下标 一个向上行使 一个向下行使
//偶数长度 因为从0开始 直接n/2得到向下行使的下标 于是向上行使的下标(n-1)/2 就可以得到的向下行使下标之前的那个数 于是这两个数就是这个序列最中间的两个数
//奇数长度 直接/2和-1/2得到的都是中间的数 于是可以遍历对调
for(i = strlen(str)/2, b = (strlen(str)-1)/2; i < strlen(str); i++, b--) //注意是 < 没有 = 因为从strlen不是从0开始
{
pz = str[i];
str[i] = str[b];
str[b] = pz;
}
}
CH11 Code answer 10:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 100
void G_String(char *);
int main(void)
{
char str[SIZE];
char end = '@';
int i = 0;
int j;
while( strncmp(str,&end,1))
{
printf("Please enter the string(enter @ to quit):");
while( str[i] = getchar(), i < SIZE - 1 )
{
if( str[i] == '\\n' )
if( (str[++i] = getchar() ) == '\\n' )
break;
i++;
}
while( getchar() != '\\n' ) //清空缓冲区
continue;
G_String(str);
printf("\\nNow give you '%s'\\n\\n",str);
for( i = SIZE - 2; i > 0 ; --i) //清空字符串 i下标也重置为0
str[i] = 0;
}
return 0;
}
void G_String(char * str)
{
int i,b;
for( i = 0, b = 0; b < strlen(str); b++)
if( isalpha(str[b]) )
str[i++] = str[b];
str[i] = '\\0';
}
CH11 Code answer 11:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define ROWS 10
#define COLS 100
char * s_gets(char * st, int n);
void Print_msg(void);
void G_ar(char (*ar)[COLS],char * ptrstr[]); //如果*ar[COLS]结合律是[]优先 那么变成指向COLS长度长的指针数组
void Print(char * ptrstr[]);
void Asc(char * ptrstr[]); //这个函数比较的是字符串首字母 而直接传入用strcmp会有const char问题
//于是按书上办法来 传入一个指针数组 那么也就需要新创建一个变量
void Len(char * ptrstr[]); //根据字符串长度排序
void F_ch(char (*ar)[COLS]);
int String_in(char * str1,char * str2);
int main(void)
{
int ch;
char ar[ROWS][COLS];
char * ptrstr[ROWS];
printf("Please enter ten string:\\n");
G_ar(ar, ptrstr);
Print_msg();
while(1)
{
printf("Your choose is ");
scanf("%d",&ch);
while(getchar() != '\\n') //遇事不决 缓冲区背锅
continue;
if( ch > 0 && ch < 5)
{
switch (ch)
{
case 1:
Print(ptrstr);
break;
case 2:
Asc(ptrstr);
Print(ptrstr);
break;
case 3:
Len(ptrstr);
Print(ptrstr);
break;
case 4:
F_ch(ar);
break;
}
Print_msg();
}
else if( ch == 5 )
{
printf("bye!");
break;
}
else
{
printf("Please enter 1~5\\n");
Print_msg();
}
}
return 0;
}
void Print_msg(void)
{
printf("\\n");
printf("***********************************************\\n");
printf("1.Print 2.Print(Ascil)\\n");
printf("3.Print(len) 4.Print(First character len)\\n");
printf("5.Quit\\n");
printf("***********************************************\\n");
}
void G_ar(char (*ar)[COLS], char *ptrstr[ROWS])
{
int ct = 0;
while(ct < ROWS && s_gets(ar[ct], COLS) != NULL && ar[ct][0] != '\\0')
{
ptrstr[ct] = ar[ct];
ct++;
}
}
void Print(char * ptrstr[])
{
int i;
for(i = 0; i < ROWS; i++)
printf("The %-3d string is %s\\n",i + 1, ptrstr[i]);
}
void Asc(char * ptrstr[])
{
int i, j;
char * tmp;
for( i = 0; i < ROWS - 1; i++)
for( j = i + 1; j < ROWS; j++)
if( strcmp(ptrstr[i],ptrstr[j]) > 0 )
{
tmp = ptrstr[i];
ptrstr[i] = ptrstr[j];
ptrstr[j] = tmp;
}
}
char * s_gets(char * st, int n)
{
char * ret_val;
ret_val = fgets(st, n, stdin);
if(ret_val)
{
while(*st != '\\n' && *st != '\\0')
st++;
if(*st == '\\n')
*st = '\\0';
else
while( getchar() != '\\0')
continue;
}
return ret_val;
}
void Len(char * ptrstr[])
{
int i, j;
char * tmp;
for(i = 0; i < ROWS - 1; i++)
for(j = i + 1; j < ROWS; j++)
if( strlen(ptrstr[i]) > strlen(ptrstr[j]) )
{
tmp = ptrstr[i];
ptrstr[i] = ptrstr[j];
ptrstr[j] = tmp;
}
}
void F_ch(char (*ar)[COLS])
{
int i,j,a,b;
char ch[ROWS][COLS] = {0}; //要记得初始化单词数组 要不然会有奇怪字符
char c;
char * tmp;
char * ptr[ROWS];
for(i = 0, a = 0, j = 0, b = 0; i < ROWS; i++, a++) //将第一个单词放入数组
{
while( !isalpha(c = ar[i][j]))//去掉空格
j++;
ch[a][b++] = ar[i][j++]; //获取已经是字母是单词首尾 然后j加到下个字符
while( isalpha( c = ar[i][j++] ) ) //存入所有单词 直到遇到第一个空格
ch[a][b++] = c;
b = 0;
j = 0;
ptr[i] = ch[i]; //思路从下面到这 从这里直接赋值到指针数组
}
/*
for( i = 0; i < ROWS - 1; i++) //排序单词数组
for( j = i + 1; j < ROWS; j++)
if( strlen(ch[i]) > strlen(ch[j])) //直接写这样的替换不行 因为这是指针数组操作
{
tmp = ch[i];
ch[i] = ch[j];
ch[j] = tmp;
}
*/
Len(ptr); //调用这个函数成功排序第一个字符
for( i = 0; i < ROWS; i++)
for( j = 0; j < ROWS; j++)
if(String_in(ar[j], ptr[i]))
{
puts(ar[j]);
break;
}
}
//这个和strstr应该是相同功能 但不能正常返回??看麻了下次找 找到咯
int String_in(char * str1, char * str2)
{
int i = 0;
int j;
while( i < strlen(str1)) //之前把i++放在这
{
if(str2[0] == str1[i]) //当在这的时候str1[i]就成1了于是不能从第0位开始
{
for( j = 1; j < strlen(str2); j++)
{
if(str2[j] != str1[i+j])
break;
}
if( strlen(str2) == j )
{
return 1;
}
}
i++; //应该是第一个字符判断之后再加
}
return 0;
}
CH11 Code answer 12:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define SIZE 100
int Word_num(char *);
int main(void)
{
int num = 0, low = 0, up = 0, bd = 0, wdnum = 0;
int i = 0;
char str[SIZE] = {0};
printf("Please enter a string:");
while( (str[i] = getchar()) != EOF)
{
if(isdigit(str[i]))
num++;
if(islower(str[i]))
low++;
if(ispunct(str[i]))
bd++;
if(isupper(str[i]))
up++;
i++;
}
wdnum = Word_num(str);
printf("The word num hava %d\\nThe num have %d\\nThe lower character have %d\\nThe punction have %d\\nThe The upper character have %d"
,wdnum,num,low,bd,up);
return 0;
}
int Word_num(char * str)
{
int i, num, flag;
for(i = 0, num = 0, flag = 0; i < strlen(str); i++)
{
if(flag == 0 && isalpha(str[i])) //单词开头是字符 flag为0(单词还没开始)
flag = 1; //flag设为1单词开始
if(flag == 1 && isspace(str[i])) //状态为是单词状态 而且到了有 空 说明单词结束
{
num++;
flag = 0; //flag设为0单词结束
}
}
return num;
}
CH11 Code answer 13:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define SIZE 100
#define CHNUM 10
int Re_String(char *, char (*ch)[SIZE]);
int main(void)
{
char str[SIZE];
char ch[CHNUM][SIZE] = {0};
int count;
printf("Please enter a string:");
fgets(str,SIZE,stdin);
count = Re_String(str, ch);
while(count--)
printf("%s ",ch[count]);
return 0;
}
int Re_String(char * str, char (*ch)[SIZE])
{
int flag, i, a, b;
for(i = 0, flag = 0, a = -1, b = 0; i < strlen(str); i++, b++)
{
if(flag == 0 && isalpha(str[i]))
{
flag = 1;
a++; //新的一个单词
b = 0; //二维下标重新重置为0
}
if(flag == 1 && isspace(str[i]))
flag = 0;
if(flag)
ch[a][b] = str[i]; //存储每个单词
}
return a + 1; //返回个数 因为主函数中用while判断0 所以+1个数
}
CH11 Code answer 14:
#include <stdio.h>
double Pow(double, int);
int main(void)
{
double kk = 1;
int n;
while(kk)
{
printf("Please enter your num(enter 0 to quit):");
scanf("%lf",&kk);
printf("Please enter the n:");
scanf("%d",&n);
printf("The answer is %lf\\n",Pow(kk,n));
}
return 0;
}
double Pow(double kk, int n)
{
int i;
double pz = 1;
for(i = 1; i <= n; i++)
{
pz = pz *kk;
}
return pz;
}
CH11 Code answer 15:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 10
int s_atoi(char *);
int Pow(int, int);
int main(void)
{
char str[SIZE];
int num = 1;
while(num)
{
printf("Please enter the num(enter !num to quit):");
scanf("%s",str);
num = s_atoi(str);
printf("%d\\n", num);
}
return 0;
}
int s_atoi(char * str)
{
int num, i;
char ch;
for(i = 0, num = 0; i < strlen(str); i++)
{
if(!isdigit(str[i]))
return 0;
ch = str[i];
num += ((int)ch - 48) * Pow(10, (strlen(str) - i - 1));
}
return num;
}
int Pow(int kk,int n)
{
int i, pz;
for(i = 0, pz = 1; i < n; i++)
{
pz *= kk;
}
return pz;
}
CH11 Code answer 16:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char * argv[]) //猜想是如果不打参数 会把 '<' 当成参数 然后文件也导入不进不去
{
char ch;
if(*argv[1])
{
switch (*argv[1])
{
case 'p':
while((ch = getchar()) != '@')
putchar(ch);
return 0;
case 'u':
while((ch = getchar()) != '@')
putchar(toupper(ch));
return 0;
case 'l':
while((ch = getchar()) != '@')
putchar(tolower(ch));
return 0;
}
}
while((ch = getchar()) != '@')
putchar(ch);
return 0;
}
以上是关于C Primer Plus(第六版)第十一章 编程练习答案的主要内容,如果未能解决你的问题,请参考以下文章