- 设计并测试一个函数,从输入中获取下n个字符(包括空白、制表 符、换行符),把结果储存在一个数组里,它的地址被传递作为一个参数。
#include <stdio.h>
#include <stdlib.h>
#define N 20
void * string_getn(char *str,int n);
int main()
{
char a[N];
string_getn(a,5);
puts(a);
return 0;
}
void * string_getn(char *str,int n){
for(int i=0;i<n;i++)
{ scanf("%c", (str+i) );}
*(str+n)='\0';
}
- 修改并编程练习1的函数,在n个字符后停止,或在读到第1个空白、 制表符或换行符时停止,哪个先遇到哪个停止。不能只使用scanf()。
#include <stdio.h>
#include <stdlib.h>
#define N 50
void * string_getn(char *str,int n);
int main()
{
char a[N];
string_getn(a,15);
puts(a);
return 0;
}
void * string_getn(char *str,int n){
int i=0;
while(i<n&& ( str[i]=getchar() )!=' '&& str[i]!='\n'&& str[i]!="\t")
i++;
*(str+i)='\0';
}
- 设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。
#include <stdio.h>
#include <stdlib.h>
void word(char * str);
int main(){
char ar[50];
word(ar);
puts(ar);
word(ar);//检测是否有缓冲区输入干扰
puts(ar);
return 0;
}
void word(char * str){
char ch;
while( ( ch=getchar() )==' ')//如果单纯的while(getchar==''){ continue;}
//会导致第一个非空格的getchar被略过,因为:getchar(非空格);
str[0]=ch; //str[i]=getchar得到的是第二个非空格数了
int i=1;
while( ( str[i]=getchar() )!='\t'&& str[i]!='\n' && str[i]!=' ')
i++;
str[i]='\0';
while(getchar()!='\n')//清除缓冲区
continue;
}
- 设计并测试一个函数,它类似编程练习3的描述,只不过它接受第2个参数指明可读取的最大字符数。
#include <stdio.h>
#include <stdlib.h>
void word(char * str,int n);
int main(){
char ar[50];
word(ar,5);
puts(ar);
return 0;
}
void word(char * str,int n){
char ch;
while( ( ch=getchar() )==' ')//如果单纯的while(getchar==''){}
continue; //会导致第一个非空格的getchar被略过,因为:getchar(非空格);
str[0]=ch; //str[i]=getchar;
int i=1;
while( ( str[i]=getchar() )!='\t'&& str[i]!='\n' && str[i]!=' '&&i<n)
i++;
str[i]='\0';
while(getchar()!='\n')
continue;
}
- 设计并测试一个函数,搜索第1个函数形参指定的字符串,在其中查 找第2个函数形参指定的字符首次出现的位置。如果成功,该函数返指向该 字符的指针,如果在字符串中未找到指定字符,则返回空指针(该函数的功 能与 strchr()函数相同)。在一个完整的程序中测试该函数,使用一个循环 给函数提供输入值
#include <stdio.h>
#include <stdlib.h>
char *find_ch(char * str, char ch);
int main(){
char ar[200];
char ch;
printf("请输入查找字符:\n");
scanf("%c",&ch);
while (getchar()!='\n') continue;
//滤掉scanf的回车,因为puts遇到回车直接结束输入
printf("请输入字符串:\n");
gets(ar);
while( '\0'!=ar[0]){//若为空输入则结束字符串输入循环
char *judge=find_ch(ar,ch);//判断是否返回空指针
if ( judge )
puts(judge);//验证:从找到的地方开始输出
else
printf("none\n");
printf("请输入字符串:\n");
gets(ar);}
printf("done!\n");
return 0;
}
char *find_ch(char * str, char ch){
while( *str!='\0'&& *str!=ch){
str++;}
if (ch==*str)
return str;
if('\0'==*str)
return NULL;
} }
- 编写一个名为is_within()的函数,接受一个字符和一个指向字符串的 指针作为两个函数形参。如果指定字符在字符串中,该函数返回一个非零值 (即为真)。否则,返回0(即为假)。在一个完整的程序中测试该函数, 使用一个循环给函数提供输入值。
#include <stdio.h>
#include <stdlib.h>
int is_within(char ch,char *ptr);
int main()
{
char input[100];
char ch;
int judge;
printf("请输入字符串(回车结束):\n");
gets(input);
while( input[0]!=0){
printf("请输入查找的字符:\n");
scanf("%c",&ch);
judge=is_within(ch,input);
printf("\n%s%c\n\n",(judge==0)?"没有找到":"找到",ch);
while (getchar() != '\n')
continue;
printf("请输入字符串(回车结束):\n");
gets(input);
}
printf("输入结束");
return 0;
}
int is_within(char ch,char *ptr){
while( *ptr!='\0'&&*ptr!=ch)
ptr++;
if (*ptr=='\0')
return 0;
else
return 1;
}
- strncpy(s1, s2, n)函数把s2中的n个字符拷贝至s1中,截断s2,或者有必要的话在末尾添加空字符。如果s2的长度是n或多于n,目标字符串不能以空字符结尾。该函数返回s1。自己编写一个这样的函数,名为mystrncpy()。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrncpy(char *target,char *source,int n);
int main()
{
char target[100];
char source[100];
printf("请输入字符串:\n");
while ( gets(source)&&source[0]!=0) //输入空line结束循环
{ mystrncpy(target,source,15);
printf("target输入:");
fputs(target,stdout);
printf(" target中有%d个字符\n",strlen(target));//测试末尾是否有换行符
printf("请输入字符串:\n");
}printf("输入结束");
return 0;
}
void mystrncpy(char *target,char *source,int n){
int i=0;
while(i<n && source[i]!=0){ //copy没满20个字符或者source没全部copy完。
target[i]=source[i];
i++;}
if(i<n-1) // 从source中copy的数量为i+1,若i+1<n,就可以在最后填上\0。
target[i]='\0';
}
对于s2(源字符串)比限定copy的最大长度n小时,会在s2的末尾添加’\0’,所以"I’m real fine"后面跟了一个空字符,字符串长度为13;当s2长度超过限定copy的字符数量时,因为目标字符串没有以空字符串结尾,目标数组s1的n(15)位后被一些奇奇怪怪的东西塞满了,直到第28个位置上被随机塞了一个’\0’字符串才结束
- 编写一个名为string_in()的函数,接受两个指向字符串的指针作为参数。如果第2个字符串中包含第1个字符串,该函数将返回第1个字符串开始的地址。例如,string_in(“hats”, “at”)将返回hats中a的地址。否则,该函数返回空指针。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *string_in(char *ptr1,char *ptr2);
int main()
{
char a[100];
char b[100];
char *find;
printf("please enter the string you are looking for:\n");
gets(b);
printf("Please enter the string you want to lookup,(enter to quit):\n");
while( gets(a)&&a[0]!='\0' ){
if( ( find=string_in(a,b) ) !=NULL )
puts(find);
else
puts("not find.");
printf("Please enter the string you want to lookup,(enter to quit):\n");
}printf("done");
return 0;
}
char *string_in(char *ptr1,char *ptr2){
int length2=strlen(ptr2);
int length1=strlen(ptr1);
int ch=ptr2[0];
int i=0;
char temp[length2+1];
while( i<=(length1-length2) )
{
if ( ptr1[i]==ch)
{
for(int j=0;j<length2;j++)
{temp[j]=ptr1[i+j];}
temp[length2]='\0';
if( strcmp(temp,ptr2)==0)
return (ptr1+i);
}
i++; }
return NULL;
}
- 编写一个函数,把字符串中的内容用其反序字符串代替。在一个完整 的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char source[100];
printf("请输入一条字符串(回车结束输入):\n");
while( gets(source)&& source[0]!='\0' ){ //gets遇到换行符抛弃并换之为\0
reverse_line(source); //第一个元素就为\0意味着空line
puts(source);
printf("请继续输入字符串(回车结束输入):\n");
}
printf("输入结束");
return 0;
}
void reverse_line(char *str){
int n=strlen(str);//原字符串有n个字符
char temp;
for(int i=0;i<n/2;i++)
{ temp=str[i]; str[i]=str[n-1-i]; str[n-1-i]=temp;}
}
- 编写一个函数接受一个字符串作为参数,并删除字符串中的空格。 在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。 该程序应该应用该函数读取每个输入的字符串,并显示处理后的字符串。
#include <stdio.h>
#include <stdlib.h>
void delete_space(char *source);
int main()
{
char source[100];
printf("输入一个字符串:\n");
while(gets(source)&&source[0]!='\0'){//空line结束
delete_space(source);
puts(source);
printf("请再输入:\n"); }
printf("输入结束");
return 0;
}
void delete_space(char *source){
int index_source=0;
int index_temp=0; // 建立一个临时数组temp来copy原数组source-
//除空格以外的所有元素,并返回给source
char temp[100];
while( source[index_source]!='\0')
{
if (source[index_source]!=' ')
{temp[index_temp]=source[index_source];
index_temp++;}
index_source++; //因为只有不为空格才抄写,所以用两组下标
}
temp[index_temp]='\0'; //copy结束
for(int i=0;i<=index_temp;i++) //返回给source数组
{
source[i]=temp[i];
}
}
- 编写一个函数,读入10个字符串或者读到EOF时停止。该程序为用 户提供一个有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按长度递增顺序打印字符串、按字符串中第1个单词的长度打印字符 串、退出。菜单可以循环显示,除非用户选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void show_menu(void);
char *s_gets(char *str,int n);
int fill_ar(char ar[][50],int n);
void func_a( char a[][50],int n);
void func_b(char a[][50],int n);
void func_c(char a[][50],int n);
void func_d(char a[][50],int n);
int main() //参考P359 sort_str.c
{
char ar[10][50];
int ct;
char ch;
ct=fill_ar(ar,10);
show_menu();
while( ( ch=getchar() ) != 'q'){
switch (ch){
case 'a':
case 'A':
func_a(ar,ct);
break;
case 'b':
case 'B':
func_b(ar,ct);
break;
case 'c':
case 'C':
func_c(ar,ct);
break;
case 'd':
case 'D':
func_d(ar,ct);
break;
default:
printf("请输入有效值a,b,c,d,q\n");
}
show_menu();
while( getchar()!='\n')
continue;
}
printf("输入结束\n");
return 0;
}
void show_menu(void){
printf("*******************************************************************\n");
printf("------------\n");
printf("请选择功能:|\n");
printf("------------\n");
printf("a.打印源字符串列表 b.ASCII顺序打印字符串\n");
printf("c.长度递增顺序打印字符串 d.第一个单词长度打印字符串 q.结束输入\n");
printf("*******************************************************************\n");
}
char *s_gets(char *str,int n)//str用来收取输入,n提示输入上限
{
char *feedback;
char *position_enter;
feedback=fgets(str,n,stdin);
//feedback返回一个指向str的指针,如果str内容为空,返回空指针NULL
if(feedback){
position_enter=strchr(str,'\n');
if(position_enter)
*position_enter='\0';
//对于str,翻遍整个字符串,有回车,则用空字符替换,结束,后面的垃圾字符就不用管了
else
while( getchar()!='\n')
;
/*如果输入阵列输入了很多个字符,超过了str的获取上限n,
直到n+1000才按下回车,则要用getchar()清除输入阵列从n+1到回车的字符*/
}
return feedback;//要么为null,要么为str首地址
}
int fill_ar(char ar[][50],int n){
printf("请输入10行,或途中以enter键结束:\n");
int ct=0;
while(ct<n&& s_gets(ar[ct],50)!=NULL&&ar[ct][0]!='\0')
/*假如什么都没输入,则为空line,那么s_gets给出fgets的返回值——NULL,如果一开始
输入了一个回车,再打算输入很多字符,就不是空line,但是在这个while中就默认开头按下
回车(被s_gets)转换为\0 是结束循环*/
ct++;
return ct;
}
void func_a( char a[][50],int n){ //打印源字符串列表
printf("\na.打印源字符串列表\n");
int i=0;
while(a[i][0]!='\0'&&i<n){
puts(a[i]); i++;
}
}
void func_b(char a[][50],int n){ //ASCII顺序打印字符串
printf("\nb.ASCII顺序打印字符串\n");
char *temp[n]; //定义了一个数组,内含n个指针(不能修改原数组)
char *exchange;
for(int i=0;i<n;i++)
temp[i]=a[i]; //顺序标定指针
//排序 指针下标随ASCII顺序递增
for(int j=0;j<n-1;j++){
for(int k=j+1;k<n;k++){
if ( strcmp(temp[j],temp[k])>0 )
{ exchange=temp[j];temp[j]=temp[k];temp[k]=exchange;}
}}
for(int i=0;i<n;i++)
puts(temp[i]);}
void func_c(char a[][50],int n){ //长度递增顺序打印字符串
printf("\nc.长度递增顺序打印字符串\n");
char *temp[n];
char *exchange;
for(int i=0;i<n;i++) //fun_c照抄fun_b,改掉判定条件if即可
temp[i]=a[i];
for(int j=0;j<n-1;j++){
for(int k=j+1;k<n;k++){
if ( strlen( temp[j] ) > strlen( temp[k] ) )
{ exchange=temp[j];temp[j]=temp[k];temp[k]=exchange;}
}}
for(int i=0;i<n;i++)
puts(temp[i]);}
void func_d(char a[][50],int n){ //第一个单词长度打印字符串
printf("\nd.第一个单词长度打印字符串\n");
char *temp[n]; //定义了一个数组,内含n个指针(不能修改原数组)
char *exchange;
int count;
int start,end;//数单词长度
int first_length[n]; //记单词长度
int exchange_count;
for(int i=0;i<n;i++)
temp[i]=a[i]; //顺序标定指针
for(int i=0;i<n;i++ ){ //给每个字符串首单词测长度
count=0;
while( *(temp[i]+count)==' ') //输入可能为 aaa,即开头可能为空格,要过滤掉
{ count++;} //count相当于一个时钟,记住第一个不为空格的位置,赋给start
start=count;
while(*(temp[i]+count)!=' '&&*(temp[i]+count)!='\0')
{ count++;}
end=count; //遇到第一个单词的结尾空格,此时count赋给end
first_length[i]=end-start; //两个空格之间才是真正的首单词长度
}
for(int j=0;j<n-1;j++){
for(int k=j+1;k<n;k++){
if ( first_length[j]>first_length[k] )
{ exchange=temp[j];temp[j]=temp[k];temp[k]=exchange;
exchange_count=first_length[j];first_length[j]=first_length[k];first_length[k]=exchange_count;
}//把首单词短的交换到前面来,同时这些字符串各自的单词计数器first_length也要随之交换
}}
for(int i=0;i<n;i++)
puts(temp[i]);
}
输入:
x position
apple tree
banana milk
chocalate and rainy day
simultaneous and instaneous
umbrella and huang feihong
at here
bang bang bang
play game
basketball game
- 编写一个程序,读取输入,直至读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h头文件中的 函数。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{ int inword;
int word=0;
int a_letter=0;
int A_letter=0;
int digit=0;
int punct=0;
char getch;
char ar[2000];
int i=0;
while( ( getch=getchar() ) != EOF ){
ar[i]=getch;i++;
}
inword=0;
for(int j=0;j<i;j++)
{
if( isalpha(ar[j]) && inword==0 )
inword=1;
if(inword==1 &&
( ispunct(ar[j]) || isspace(ar[j]) ) )
{ word++;
inword=0;}
if( islower(ar[j]) )
a_letter++;
if( isupper(ar[j]))
A_letter++;
if( isdigit(ar[j]) )
digit++;
if( ispunct( ar[j] ) )
punct++; }
printf("%d punctuation , %d lower letter , %d upper letter , %d word and %d digit",
punct,a_letter,A_letter,word,digit);
return 0;
}
- 编写一个程序,反序显示命令行参数的单词。例如,命令行参数是 see you later,该程序应打印later you see。
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char * argv[])
{
int count;
for(count=argc-1;count>0;count--)
printf("%s ",argv[count]);
printf("\n");
return 0;
}
- 编写一个通过命令行运行的程序计算幂。第1个命令行参数是double 类型的数,作为幂的底数,第2个参数是整数,作为幂的指数。
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char * argv[])
{
float total=1;
float base=atof(argv[1]);
int power=atoi(argv[2]);
if(base==0)
{
if(power==0)
{printf("It is not defined\n");
printf("0 power of 0 is 0\n"); }
else
{ printf("%d power of 0 is 0\n",power);}
}
else
{
if(power>0)
{ for(int i=0;i<power;i++){
total*=base;}
printf("%d power of %f is %f\n",power,base,total);
}
else if(power<0)
{ for(int i=0;i<(-1)*power;i++){
total*=base;}
printf("%d power of %f is %f\n",power,base,1/total);
}
else {printf("%d power of %f is 1\n",power,base); }
}
return 0;
}
- 使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字, 该函数返回0。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int go_atoi(char *ptr);
int main()
{
char a[50];
printf("字符串输入:\n");
gets(a);
printf("数字输出:\n");
printf("%d\n",go_atoi(a));
return 0;
}
int go_atoi(char *ptr){
int i=0;
int ten_power=1;
int sum=0;
while(ptr[i]!='\0'){
if( !isdigit(ptr[i]) )
{
return 0; //检查从头到尾有没有非数字,记得不要用fget,
//fget会录入回车
}
i++;
}
i--; //这里的i--是最后一个数字(个位)的下标
sum=ptr[i]-'0'; //把个位加给sum , 数字字符的ASCII码在48-57之间
while(--i>=0)
{ten_power*=10; // i每次减1都升位
sum+=(ptr[i]-'0')*ten_power;//百位乘百,千位乘千,加给sum
}
return sum;
}
- 编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出
来。该程序识别和实现下面的命令行参数:
-p 按原样打印
-u 把输入全部转换成大写
-l 把输入全部转换成小写
如果没有命令行参数,则让程序像是使用了-p参数那样运行。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc,char * argv[])
{
char ch;
if ( strcmp(argv[1],"-u")==0 )
while( (ch=getchar())!=EOF){
if( isalpha(ch) )
{ ch=toupper(ch);
putchar(ch);}
else
putchar(ch);
}
if( strcmp(argv[1],"-l")==0 )
while( (ch=getchar())!=EOF){
if( isalpha(ch) )
{ ch=tolower(ch);
putchar(ch);}
else
putchar(ch);
}
if( strcmp(argv[1],"-p")==0 || argv[1]==NULL)//*直接输入程序名加enter没有实现-p输出
while( (ch=getchar())!=EOF)
putchar(ch);
return 0;
}