复杂指针-指针数组&多级指针&函数指针 指定位置输出字符串 本题要求实现一个函数,对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符。
函数接口定义: 1 char *match ( char *s, char ch1, char ch2 ) ;
函数match
应打印s
中从ch1
到ch2
之间的所有字符,并且返回ch1
的地址。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> #define MAXS 10 char *match ( char *s, char ch1, char ch2 ) ;int main () { char str[MAXS], ch_start, ch_end, *p; scanf ("%s\n" , str); scanf ("%c %c" , &ch_start, &ch_end); p = match (str, ch_start, ch_end); printf ("%s\n" , p); return 0 ; }
输入样例1:
输出样例1:
输入样例2:
输出样例2:
输入样例3:
输出样例3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 char *match ( char *s, char ch1, char ch2 ) { char *p=NULL ; int i; for (i=0 ;i<strlen (s)&&s[i]!=ch1;i++) { } p=&s[i]; for (;i<strlen (s);i++) { printf ("%c" ,s[i]); if (s[i]==ch2) { break ; } } printf ("\n" ); return p; }
查找子串 本题要求实现一个字符串查找的简单函数。
函数接口定义: 1 char *search ( char *s, char *t ) ;
函数search
在字符串s
中查找子串t
,返回子串t在s
中的首地址。若未找到,则返回NULL。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> #define MAXS 30 char *search (char *s, char *t) ;void ReadString ( char s[] ) ; int main () { char s[MAXS], t[MAXS], *pos; ReadString (s); ReadString (t); pos = search (s, t); if ( pos != NULL ) printf ("%d\n" , pos - s); else printf ("-1\n" ); return 0 ; }
输入样例1: 1 2 The C Programming Language ram
输出样例1:
输入样例2: 1 2 The C Programming Language bored
输出样例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 char *search (char *s, char *t) { int lens = strlen (s); int lent = strlen (t); int i,j,k=0 ; char *p=NULL ; for (i=0 ;i<lens;i++) { j=i; while (s[j] == t[k]) { j++; k++; } if (k>=lent) { p=&s[i]; return p; } k = 0 ; } return p; }
找密码 在一个古堡的大门上有5行字符。其中隐藏着打开大门的密码。密码共有4位数字(0到9)。小明发现了一种找密码的方法:最后一行中的字符在第一行字符中出现的总次数是密码的第一个数字,依此类推。输入数据保证每行得到的数字在0到9之间。 请编写一个函数 decode帮助小明找出密码。
函数接口定义:
通过参数s向函数传递5行字符串,函数返回密码值。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> #include <stdlib.h> #define N 100 #define M 5 int decode (char **s) ;int main () { char *s[M]; int i; int key; for (i=0 ; i<M; i++){ s[i] = (char *)malloc ((N+1 )*sizeof (char )); gets(s[i]); } key = decode(s); printf ("%04d" ,key); for (i=0 ; i<M; i++){ free (s[i]); } return 0 ; }
输入样例:
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int decode (char **s) { int sum=0 ; int i,j,k,t; for (i=0 ;i<4 ;i++) { t=0 ; for (j=0 ;j<strlen (s[i]);j++) { for (k=0 ;k<strlen (s[4 ]);k++) { if (s[i][j]==s[4 ][k]) { t++; } } } sum=sum*10 +t; } return sum; }
分词并显示 程序的功能是:调用Input函数读入最多80个字符,要求字符串中只保留字母和空格,遇到读满或者回车结束读入字符,空格用于分隔单词。请将字符串中用空格分隔的单词在屏幕上输出来。 要求用指针完成函数中各参数的传递与访问,自定义函数头和函数体中不得出现数组下标形式的表示法。
函数接口定义: 1 2 void Input ( char *str ) ;int Split_Count ( char *str,char **pStr ) ;
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <stdio.h> void Input ( char *str ) ;int Split_Count ( char *str,char **pStr ) ;int main (void ) { char String[81 ]={0 }, *pString[45 ]; int i=0 , count; Input (String); count = Split_Count (String, pString); printf ("%d Words: " , count); for (i=0 ; i<count-1 ; i++) { printf ("%s-" , pString[i]); } printf ("%s" , pString[count-1 ]); putchar ('\n' ); return 0 ; }
输入样例: 1 Actions speak louder than words
输出样例: 1 5 Words: Actions-speak-louder-than-words
输入样例: 1 12A good && beginning is half @done
输出样例: 1 6 Words: A-good-beginning-is-half-done
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 void Input ( char *str ) { char x; int i=1 ; x=getchar(); while (x!='\n' &&i<81 ) { if ((x>='a' &&x<='z' )||(x>='A' &&x<='Z' )||x==' ' ) { str[i-1 ]=x; i++; } x=getchar(); } *(str+i)='\0' ; } int Split_Count ( char *str,char **pStr ) { int count=0 ; while (*str) { if (*str!=' ' ) { *(pStr+count)=str; count++; } while (*str) { if (*str==' ' ) { *str='\0' ; break ; } str++; } str++; } return count; }
链表复杂操作 链表逆置 本题要求实现一个函数,将给定单向链表逆置,即表头置为表尾,表尾置为表头。链表结点定义如下:
1 2 3 4 struct ListNode { int data; struct ListNode *next; };
函数接口定义: 1 struct ListNode *reverse ( struct ListNode *head ) ;
其中head
是用户传入的链表的头指针;函数reverse
将链表head
逆置,并返回结果链表的头指针。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next ; }; struct ListNode *createlist () ; struct ListNode *reverse ( struct ListNode *head ) ;void printlist ( struct ListNode *head ) { struct ListNode *p = head; while (p) { printf ("%d " , p->data); p = p->next; } printf ("\n" ); } int main () { struct ListNode *head ; head = createlist (); head = reverse (head); printlist (head); return 0 ; }
输入样例:
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 struct ListNode *reverse ( struct ListNode *head ) { struct ListNode *p = head,*q=NULL ; struct ListNode *newHead = (struct ListNode *)malloc (sizeof (struct ListNode)); newHead->next=NULL ; while (p) { q=p->next; p->next=newHead->next; newHead->next=p; p=q; } return newHead->next; }
链表拼接 本题要求实现一个合并两个有序链表的简单函数。链表结点定义如下:
1 2 3 4 struct ListNode { int data; struct ListNode *next; };
函数接口定义: 1 struct ListNode *mergelists (struct ListNode *list1, struct ListNode *list2) ;
其中list1
和list2
是用户传入的两个按data
升序链接的链表的头指针;函数mergelists
将两个链表合并成一个按data
升序链接的链表,并返回结果链表的头指针。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next ; }; struct ListNode *createlist () ; struct ListNode *mergelists (struct ListNode *list1, struct ListNode *list2) ;void printlist ( struct ListNode *head ) { struct ListNode *p = head; while (p) { printf ("%d " , p->data); p = p->next; } printf ("\n" ); } int main () { struct ListNode *list1 , *list2 ; list1 = createlist (); list2 = createlist (); list1 = mergelists (list1, list2); printlist (list1); return 0 ; }
输入样例:
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 struct ListNode *mergelists (struct ListNode *list1, struct ListNode *list2) { struct ListNode *list = (struct ListNode *)malloc (sizeof (struct ListNode)); struct ListNode *p =list ; while (list1&&list2) { if (list1->data<list2->data) { list ->next=list1; list1=list1->next; list =list ->next; } else { list ->next=list2; list2=list2->next; list =list ->next; } } while (list1) { list ->next=list1; list1=list1->next; list =list ->next; } while (list2) { list ->next=list2; list2=list2->next; list =list ->next; } return p->next; }
逆序数据建立链表 本题要求实现一个函数,按输入数据的逆序建立一个链表。
函数接口定义: 1 struct ListNode *createlist () ;
函数createlist
利用scanf
从输入中获取一系列正整数,当读到−1时表示输入结束。按输入数据的逆序建立一个链表,并返回链表头指针。链表节点结构定义如下:
1 2 3 4 struct ListNode { int data; struct ListNode *next ; };
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next ; }; struct ListNode *createlist () ;int main () { struct ListNode *p , *head = NULL ; head = createlist (); for ( p = head; p != NULL ; p = p->next ) printf ("%d " , p->data); printf ("\n" ); return 0 ; }
输入样例:
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct ListNode *createlist () { int data=-1 ; struct ListNode *head = (struct ListNode *)malloc (sizeof (struct ListNode)),*cur=NULL ; head->next=NULL ; while (scanf ("%d" ,&data)&&data!=-1 ) { cur=(struct ListNode *)malloc (sizeof (struct ListNode)); cur->data=data; cur->next=head->next; head->next=cur; } return head->next; }
单链表结点删除 本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:
1 2 3 4 struct ListNode { int data; ListNode *next; };
函数接口定义: 1 2 struct ListNode *readlist () ;struct ListNode *deletem ( struct ListNode *L, int m ) ;
函数readlist
从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。
函数deletem
将单链表L
中所有存储了m
的结点删除。返回指向结果链表头结点的指针。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next ; }; struct ListNode *readlist () ;struct ListNode *deletem ( struct ListNode *L, int m ) ;void printlist ( struct ListNode *L ) { struct ListNode *p = L; while (p) { printf ("%d " , p->data); p = p->next; } printf ("\n" ); } int main () { int m; struct ListNode *L = readlist (); scanf ("%d" , &m); L = deletem (L, m); printlist (L); return 0 ; }
输入样例:
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 struct ListNode *readlist () { int data=0 ; struct ListNode *head =NULL ,*tail=NULL ; while (scanf ("%d" ,&data)&&data!=-1 ) { struct ListNode *cur = (struct ListNode *)malloc (sizeof (struct ListNode)); cur->data=data; cur->next=NULL ; if (head==NULL ) { head=tail=cur; } else { tail->next=cur; tail=cur; } } return head; } struct ListNode *deletem ( struct ListNode *L, int m ) { struct ListNode *p =NULL ,*q=NULL ,*head=NULL ; head=L; while (head&&head->data==m) { p=head->next; free (head); head=p; } q = head; p = head->next; while (p != NULL ) { if (p->data == m) { q->next = p->next; free (p); } else { q = p; } p = p->next; } return head; }
学生成绩链表处理 6-3 学生成绩链表处理 (20 分)
本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。
函数接口定义: 1 2 struct stud_node *createlist () ;struct stud_node *deletelist ( struct stud_node *head, int min_score ) ;
函数createlist
利用scanf
从输入中获取学生的信息,将其组织成单向链表,并返回链表头指针。链表节点结构定义如下:
1 2 3 4 5 6 struct stud_node { int num; char name[20 ]; int score; struct stud_node *next ; };
输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。
函数deletelist
从以head
为头指针的链表中删除成绩低于min_score
的学生,并返回结果链表的头指针。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <stdio.h> #include <stdlib.h> struct stud_node { int num; char name[20 ]; int score; struct stud_node *next ; }; struct stud_node *createlist () ;struct stud_node *deletelist ( struct stud_node *head, int min_score ) ;int main () { int min_score; struct stud_node *p , *head = NULL ; head = createlist (); scanf ("%d" , &min_score); head = deletelist (head, min_score); for ( p = head; p != NULL ; p = p->next ) printf ("%d %s %d\n" , p->num, p->name, p->score); return 0 ; }
输入样例: 1 2 3 4 5 6 1 zhang 78 2 wang 80 3 li 75 4 zhao 85 0 80
输出样例:
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 struct stud_node *createlist () { int num; struct stud_node *head =NULL ,*tail=NULL ,*cur=NULL ; while ((scanf ("%d" ,&num)&&num!=0 )) { cur=(struct stud_node *)malloc (sizeof (struct stud_node)); cur->num=num; scanf ("%s %d" ,cur->name,&cur->score); if (head==NULL ) { head=tail=cur; } else { tail->next=cur; tail=cur; } } return head; } struct stud_node *deletelist ( struct stud_node *head, int min_score ) { sstruct stud_node *p=NULL ,*q=NULL ; while (head) { if (head->score<min_score) { p=head; head=head->next; free (p); } else { break ; } } if (head==NULL ) return NULL ; q=head; p=head->next; while (p) { if (p->score<min_score) { q->next=p->next; free (p); } else { q=p; } p=p->next; } return head; }
文件操作 从文件读取字符串(*) 请编写函数,从文件中读取字符串。
函数原型 1 void FGetStr (char *str, int size, FILE *file) ;
说明:参数 str 为指示字符数组起始地址的指针,size 为数组尺寸,file 为文件指针。函数从文件输入的字符串(以换行符 ‘\n’ 结束)到字符数组中,并在字符末尾添加字符串结束标记 ‘\0’。显然,字符串的最大长度应为 size - 1,为字符串结束标记 ‘\0’ 预留空间。若用户输入的字符过多,则函数最多读取 size - 1 个字符,剩余字符仍留在缓冲区中,可以继续被后面的输入函数读取。
要求:不得把文件中的换行符 ‘\n’ 也保存到字符串中。
裁判程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> #include <string.h> void FGetStr (char *str, int size, FILE *file) ;int main () { FILE *f; char a[10 ], b[10 ]; f = fopen("MyStr.txt" , "r" ); if (f) { FGetStr(a, 10 , f); FGetStr(b, 10 , f); puts (a); puts (b); fclose(f); } return 0 ; }
创建文本文件 MyStr.txt,复制下面的内容。
输出样例1
修改文本文件 MyStr.txt,复制下面的内容。
输出样例2
修改文本文件 MyStr.txt,复制下面的内容。
输出样例3
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void FGetStr (char *str, int size, FILE *file) { int i=0 ; char ch; ch=fgetc(file); while (ch!='\n' &&i<size-1 &&ch!=EOF) { str[i]=ch; i++; ch=fgetc(file); } if (ch!='\n' ) { ungetc(ch,file); } str[i]='\0' ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 int CountWord (FILE *f) { int count=0 , flag; char ch; while ((ch=fgetc(f))!=EOF) { if (ch>='a' &&ch<='z' ||ch>='A' &&ch<='Z' ) { flag=1 ; } if (!(ch>='a' &&ch<='z' ||ch>='A' &&ch<='Z' )&&flag==1 ) { flag=0 ; count++; } if (!(ch>='a' &&ch<='z' ||ch>='A' &&ch<='Z' )&&flag==0 ) { continue ; } } if (count==0 &&flag==1 ) return 1 ; else if (count==0 &&flag==0 ) return 0 ; else return count; }
文件读写操作 编写函数,从给定的输入文本文件中按行读入,并按行写入给定的输出文件中。要求:1)去除每行的前导空格或制表符。2)每行前加行号。
函数接口定义: 1 void fileRW (FILE *fin,FILE *fout) ;
其中fin
和fout
都是用户传入的参数,分别是读入文件和输出文件的指针(已按要求打开)。
裁判测试程序样例: 1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> void fileRW (FILE *fin,FILE *fout) ;int main () { char fname[20 ];gets(fname); FILE *fpr=fopen(fname,"r" ); FILE *fpw=fopen("file2.txt" ,"w" ); fileRW(fpr,fpw); fclose(fpr);fclose(fpw); return 0 ; }
输入样例: 输入文件名:file1.cpp,其中内容为:
1 2 3 4 5 6 7 void fileW(){ FILE *fp1=fopen("myfile.data","w"); int i=123;float x=3.14159; fprintf(fp1,"%d,%5d,%5.3f\n",i,-i,x); fprintf(stdout,"%d,%5d,%5.3f\n",i,-i,x); fclose(fp1); }
输出样例: 文件:file2.txt,其中内容为:
1 2 3 4 5 6 7 1:void fileW(){ 2:FILE *fp1=fopen("myfile.data","w"); 3:int i=123;float x=3.14159; 4:fprintf(fp1,"%d,%5d,%5.3f\n",i,-i,x); 5:fprintf(stdout,"%d,%5d,%5.3f\n",i,-i,x); 6:fclose(fp1); 7:}
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 void fileRW(FILE *fin,FILE *fout) { char ch; int i=1,j=1; while(1) { ch=fgetc(fin); if(i==j&&ch!=EOF) { fprintf(fout,"%d:",j++); while(ch==' '||ch=='\t') { ch=fgetc(fin); } } if(ch=='\n') { i++; } if(ch==EOF) { break; } fputc(ch,fout); } }