1/设计并测试一个函数,可以从输入读取n个字符(包括空格、制表符和换行符),把结果存储在一个数组中,这个数组的地址通过参数来传递。
#include <stdio.h>
void input(char *p, int n);
int main(void)
{
char a[81];
int n;
puts("input the char number of your string:");
scanf("%d",&n);
getchar(); //滤去回车
puts("input your string:");
input(a,n);
puts(a);
return 0;
}
void input(char *p, int n)
{
int i;
for (i=0;i<n;i++)
*(p+i) = getchar();
*(p+i) = '\0';
}
2/修改并测试练习1中的函数,使得可以在n个字符后,或第一个空格、制表符、换行符后停止读取输入,由上述情况中最先被满足的那个终止读取(不能用scanf()函数)。
#include <stdio.h>
#include <ctype.h>
void input(char *p, int n);
int main(void)
{
char a[81];
int n;
puts("input the char number of your string:");
scanf("%d",&n);
getchar(); //滤去回车
puts("input your string:");
input(a,n);
puts(a);
return 0;
}
void input(char *p, int n)
{
int i;
for (i=0;i<n;i++)
{
*(p+i) = getchar();
if( isspace(*(p+i)) ) break;
}
*(p+i) = '\0';
}
3/设计并测试一个函数,其功能是读取输入行里的第一个单词到数组,并丢掉该行中其他的字符。一个单词的定义是一串字符,其中不含空格、制表符和换行符。
#include <stdio.h>
#include <ctype.h>
void word(char *p);
int main(void)
{
char a[81];
puts("input your string:");
gets(a);
word(a);
puts(a);
return 0;
}
void word(char *p)
{
int begin,end;
for(begin=0; isspace( *(p+begin) ) ;begin++) continue;
for(end=begin; !isspace( *(p+end) ) ;end++) continue;
*(p+end) = '\0';
for(; *(p + begin) != '\0'; p++)
*p = *(p + begin);
*p = '\0';
}
4/设计并测试一个函数,其功能是搜索由函数的第一个参数指定的字符串,在其中查找由函数的第二个参数指定的字符的第一次出现的位置。如果找到,返回指向这个字符的指针:如果没有找到,返回空字符(这种方式和strchr()函数的功能一样)。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include <stdio.h>
char *mystrchr(char *, char );
int main(void)
{
char str[81];
char ch;
char *p;
do
{
puts("input range string:");
gets(str);
puts("input match char:");
ch = getchar();
getchar();
p = mystrchr(str, ch);
if ( p )
{
puts("Find!");
puts(p);
}
else puts("Can't find!");
puts("input any char except q to go on.");
gets(str);
}
while(*str != 'q');
puts("Quit.");
return 0;
}
char *mystrchr(char *p, char ch)
{
char *p_save = p;
if(*p == '\0') return NULL;
while(1)
{
if(*p == ch)
{
return p_save;
}
else
{
if(*++p == '\0') return NULL;
p_save = p;
}
}
}
5/编写一个函数is_witlun()。它接受两个参数,一个是字符,另一个是字符串指针。其功能是如果字符在字符串中,就返回一个非O值(真);如果字符不在字符串中,就返回O值(假)。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include <stdio.h>
int is_within(char *p, char ch);
int main(void)
{
char str[81];
char ch;
do
{
puts("input range string:");
gets(str);
puts("input match char:");
ch = getchar();
getchar();
if ( is_within(str, ch) ) puts("Find!");
else puts("Can't find!");
puts("input any char except q to go on.");
ch = getchar();
getchar();
}
while(ch != 'q');
puts("Quit.");
return 0;
}
int is_within(char *p, char ch)
{
while(*p != '\0')
{
if(*p == ch) return 1;
p++;
}
return 0;
}
strncpy (sl,s2,n)
6/函数从s2复制n个字符给sl,并在必要时截断s2或为其填充额外的空字符。如果s2的长度等于或大于n,目标字符串就没有标志结束的空字符。函数返回sl。自己编写这个函数,并在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include <stdio.h>
char *mystrncpy(char *p1, char *p2, int n);
int main(void)
{
char str1[81];
char str2[81];
int n;
do
{
puts("input string1:");
gets(str1);
puts("input string2:");
gets(str2);
puts("input the number of copying char:");
scanf("%d",&n);
getchar();
puts("After copying:");
puts(mystrncpy(str1, str2, n));
puts("input any char except q to go on.");
gets(str1);
}
while(*str1 != 'q');
puts("Quit.");
return 0;
}
char *mystrncpy(char *p1, char *p2, int n)
{
char *p=p1;
while(*p1++ != '\0') continue;
*--p1 = *p2;
n--;
while(n>0 && *p2 != '\0')
{
*++p1 = *++p2;
n--;
}
return p;
}
7/编写一个函数string_in(),它接受两个字符串指针参数。如果第二个字符串被包含在第一个字符串中,函数就返回被包含的字符开始的地址。例如,string_in("hats","at")返回hats中a的地址,则,函数返回空指针。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include <stdio.h>
char *string_in(char *p1, char *p2);
int main(void)
{
char str1[81];
char str2[21];
char *p;
do
{
puts("input range string:");
gets(str1);
puts("input match string:");
gets(str2);
p = string_in(str1, str2);
if ( p )
{
puts("Find!");
puts(p);
}
else puts("Can't find!");
puts("input any char except q to go on.");
gets(str1);
}
while(*str1 != 'q');
puts("Quit.");
return 0;
}
char *string_in(char *p1, char *p2)
{
char *p1_save = p1, *p2_save = p2;
if(*p1 == '\0' || *p2 == '\0') return NULL;
while(1)
{
if(*p1 == *p2)
{
if(*++p2 == '\0') return p1_save;
if(*++p1 == '\0') return NULL;
}
else
{
if(*++p1 == '\0') return NULL;
p1_save = p1;
p2 = p2_save;
}
}
}
8/编写一个函数,其功能是使输入字符串反序。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。
#include <stdio.h>
void reverse(char *p);
int main(void)
{
char str[81];
do
{
puts("input a string:");
gets(str);
reverse(str);
puts(str);
puts("input any char except q to go on.");
gets(str);
}
while(*str != 'q');
puts("Quit.");
return 0;
}
void reverse(char *p)
{
int i,n;
char temp;
for(n=0; *(p+n) != '\0'; n++) continue;
n--;
for(i=0; i < n-i; i++)
{
temp = p[i];
p[i] = p[n-i];
p[n-i] = temp;
}
}
9/编写一个函数。其参数为一个字符串,函数删除字符串中的空格。在一个可以循环读取的程序中进行测试,直到用户输入空行。对于任何输入字符串,函数都应该适用并可以显示结果。
#include <stdio.h>
void delspace(char *p1);
int main(void)
{
char str[81];
do
{
puts("input a string:");
gets(str);
delspace(str);
puts(str);
puts("input any char except q to go on.");
gets(str);
}
while(*str != 'q');
puts("Quit.");
return 0;
}
void delspace(char *p1)
{
char *p2;
while (*p1 != '\0' )
{
if (*p1 == ' ')
{
p2 = p1;
while(*p2 != '\0')
{
*p2 = *(p2+1);
p2++;
}
p1--; //抵消下面的p1++
}
p1++;
}
}
10/编写一个程序,读取输入,直到读入了10个字符串或遇到EOF,由二者中最先被满足的那个终止读取过程。这个程序可以为用户提供一个有5个选项的菜单:输出初始字符串列表、按ASCII顺序输出字符串、按长度递增顺序输出字符串、按字符串中第一个单词的长度输出字符串和退出。菜单可以循环,直到用户输入退出请求。当然,程序要能真正完成菜单中的各项功能。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void origin_put(char **p, int n);
void ascii_put(char **p, int n);
void length_put(char **p, int n);
int first_word_length(char *p);
int first_word_length(char *p);
void word_put(char **p, int n);
int main(void)
{
char str[10][81];
char *p[10];
char command[10];
int n;
while(1)
{
n = 0;
puts("input no more than 10 strings finished by EOF (^Z):");
do
{
if ( gets(str[n]) == NULL ) break;
p[n] = str[n];
n++;
}
while( n<10 );
puts("select:");
puts("a. put originally");
puts("b. put in order of ascii");
puts("c. put in order of string's length");
puts("d. put in order of first word's length");
puts("e. input strings again");
puts("q. quit");
do
{
gets(command);
switch(command[0])
{
case 'a': puts("put originally:"); origin_put(p,n); break;
case 'b': puts("put in order of ascii:"); ascii_put(p,n); break;
case 'c': puts("put in order of string's length:"); length_put(p,n); break;
case 'd': puts("put in order of first word's length:"); word_put(p,n); break;
case 'e': break;
default : puts("Quit."); return 0;
}
}
while( command[0] != 'e' );
}
}
void origin_put(char **p, int n)
{
int i;
for(i=0; i<n; i++)
puts(p[i]);
}
void ascii_put(char **p, int n)
{
int i,j;
char *temp;
for(i=0; i<n; i++)
for(j=0; j<n-i-1; j++)
if (strcmp( p[j], p[j+1] ) > 0)
{
temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}
origin_put(p,n);
}
void length_put(char **p, int n)
{
int i,j;
char *temp;
for(i=0; i<n; i++)
for(j=0; j<n-i-1; j++)
if ( strlen(p[j]) > strlen(p[j+1]) )
{
temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}
origin_put(p,n);
}
int first_word_length(char *p)
{
int i=0;
for (; !isalpha(*p); p++)
if (*p == '\0') return 0;
for (i=1; isalpha(p[i]); i++) continue;
return i;
}
void word_put(char **p, int n)
{
int i,j;
char *temp;
for(i=0; i<n; i++)
for(j=0; j<n-i-1; j++)
if ( first_word_length(p[j]) > first_word_length(p[j+1]) )
{
temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}
origin_put(p,n);
}
11/编写一个程序。功能是读取输入,直到遇到EOF,并报告单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h系列的函数。
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int word=0,upper=0,lower=0,punct=0,digit=0,begin=0;
char ch;
while( ( ch = getchar() ) != EOF )
{
if( isalpha(ch) )
{
if (begin == 0)
{
word++;
begin = 1;
}
}
else begin = 0;
if( isupper(ch) ) upper++;
if( islower(ch) ) lower++;
if( ispunct(ch) ) punct++;
if( isdigit(ch) ) digit++;
}
printf("word:%d\nupper:%d\nlower:%d\npunct:%d\ndigit:%d\n",word,upper,lower,punct,digit);
return 0;
}
12/编写一个程序,按照相反的单词顺序显示命令行参数。即,如果命令行参数是see you later,程序的显示应该为later you see。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char str[81];
char *p, temp;
int i,n,length;
gets(str);
for (p = str,i=0,n = strlen(str); i<n/2; i++)//将整个字符串倒序
{
temp = *(p+n-1-i);
*(p+n-1-i) = *(p+i);
*(p+i) = temp;
}
puts(str);
p = str;
length=0;
do //将字符串中的每个单词倒序
{
if( isalpha(*p) )
{
length++;
}
else
{
if(length>1)
for(i=0; i<length/2; i++)
{
temp = *(p-1-i);
*(p-1-i) = *(p-length+i);
*(p-length+i) = temp;
}
length = 0;
}
}
while(*p++ != '\0');
puts(str);
return 0;
}
13/编写一个计算乘幂的基于命令行的程序。第一个命令行参数为double类型数,作为幂的底数;第二个参数为整数,作为幂的指数。
#include <stdio.h>
double mypower(double base, int exp);
int main(void)
{
double base;
int exp;
printf("input base number and exp:");
scanf("%lf%d", &base, &exp);
printf("%g^%d= %g\n", base, exp, mypower(base,exp) );
return 0;
}
double mypower(double base, int exp)
{
double power = 1;
if (exp<0)
power = 1/mypower(base, -exp);
else if (exp>0)
while( exp-- > 0 )
power *= base;
else if(base!=0)
power = 1;
else
power = 1/base;//0的0次幂应是一个无意义数
return power;
}
14/使用字符分类函数实现atoi()函数。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
double myatof(char *p);
int main(void)
{
char a[30]={0};
while(a[0] != 'q')
{
puts("input a double without +-e:");
gets(a);
printf("atof: %.5lf\n",atof(a));
printf("myatof: %.5lf\n",myatof(a));
printf("difference:%.5lf\n", atof(a) -myatof(a));
puts("input any char except q to go on.");
gets(a);
}
puts("Quit.");
return 0;
}
double myatof(char *p)//将字符串转换为浮点型,暂时只限小数点格式(如:342.678)
{
double n=0;
int i=-1;
while( 1 )
{
if (isdigit(*p)) //如果是数字
{
n = n*10 + (*p) -'0';
if(i != -1) i++; //小数位数i计数
}
else if ( *p == '.' && i == -1) //如果是第一个小数点
i=0; //开启小数位数i计数
else
break;
p++;
}
for(; i>0; i--) //根据小数位数i,将n取为原来的(10^i)分之一
n /= 10;
return n;
}
15/编写一个程序,其功能是读取输入,直到遇到文件结尾,并把文件显示出来。要求程序可以识别并执行下面的命令行参数:
┏━━━━┳━━━━━━━━━━━┓
┃ -p ┃按照原样显示输入 ┃
┣━━━━╋━━━━━━━━━━━┫
┃ -u ┃把输入全部转换为大写 ┃
┣━━━━╋━━━━━━━━━━━┫
┃ -l ┃把输入全部转换为小写 ┃
┗━━━━┻━━━━━━━━━━━┛
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
char ch;
if (argv[1][0] == '-') //注意argv[0]是EXE的路径,所以参数是argv[1]、argv[2]……
if (argv[1][1] == 'u')
while(( ch=getchar() ) != EOF) putchar( toupper(ch) );
else if (argv[1][1] == 'l')
while(( ch=getchar() ) != EOF) putchar( tolower(ch) );
else if (argv[1][1] == 'p')
while(( ch=getchar() ) != EOF) putchar(ch);
return 0;
}