目录
第八章(指针),第九章(指针和数组),第十章(字符串)思维导图
作业1 逆序打印
解答:
答案:
作业2 判断回文
解答:
答案:
作业3 比较单词
解答:
答案:
619作业1:搜索字符串末尾
解答:
答案:
619作业2:自己版本的 strlen
解答:
619作业3:自己版本的 strcpy
解答:
619作业4:自己版本的 strcat
解答:
619作业5:自己版本的 strcmp
解答:
作业1 逆序打印
(a) 编写程序读一条消息,然后逆序打印这条消息:
Enter a message: Don't get mad, get even.
Reversal is: .neve teg ,dam teg t'noD
提示:一次读取消息中的一个字符(用getchar函数),并且把这些字母存储在数组中,当数组满了或者读到字符 '\n' 时停止读操作。
(b) 修改上述程序,用指针代替整数来跟踪数组的当前位置。
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAX_NUM 1000
void read_char(char* str, int len) {
char c; int i = 0;
while ((c = getchar()) != '\n') {
str[i++] = c;
}
str[i] = '\0';
}
void re_print(char* str, int len) {
int i = 0;
for (i = 0; str[i]; i++)
;
i--;
for (; i != 0; i--) {
putchar(str[i]);
}
putchar(str[i]);
putchar('\n');
}
void re_print02(char* str, int len) {
char* p = str;
while (*p++)
;
p--; p--;
while ( p != str) {
putchar(*p--);
}
putchar(*p);
putchar('\n');
}
int main(void) {
char str[MAX_NUM];
printf("Enter a message: ");
read_char(str, MAX_NUM);
printf("Reversal is: ");
re_print(str, MAX_NUM);
re_print02(str, MAX_NUM);
return 0;
}
答案:
不是使用函数,录入的指针P可以直接使用逆序输出
(n < MAXLINE && (c = getchar()) != '\n' 必须检查数组是否越界,顺序不能改变(逻辑)(a) #include <stdio.h> #define MAXLINE 128 int main(void) { printf("Enter a message: "); char message[MAXLINE]; int n = 0; char c; while (n < MAXLINE && (c = getchar()) != '\n') { message[n] = c; n++; } // n == MAXLINE || c == '\n' printf("Reversal is: "); for (int i = n - 1; i >= 0; i--) { putchar(message[i]); } putchar('\n'); return 0; } (b) #include <stdio.h> #define MAXLINE 128 int main(void) { printf("Enter a message: "); char message[MAXLINE]; char* p = message; char c; while (p < message + MAXLINE && (c = getchar()) != '\n') { *p++ = c; } // p == message + MAXLINE || c == '\n' // p 指向最后一个字符后面 printf("Reversal is: "); p--; while (p >= message) { putchar(*p--); } putchar('\n'); return 0; }
作业2 判断回文
(a) 编写程序读一条消息,然后检查这条消息是否是回文(消息从左往右看和从右往左看是一样的):
Enter a message: He lived as a devil, eh?
Palindrome
Enter a message: Madam, I am Adam.
Not a palindrome
忽略所有不是字母的字符。用索引来跟踪数组中的位置。
(b)修改上述程序,使用指针代替索引来跟踪数组中的位置。
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#define MAX_NUM 1000
//首字母大小写不限,单词断句是一样的,符号对比忽略
void read_char(char* str, int len) {
char c;
char *p1 = str;
bool blank=true;
//忽略字母前面的空白字符
while ((c = getchar()) == ' ')
;
*p1++ = c;
while ((c = getchar()) != '\n') {
//符号处理
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { //字母判断!可恶!
*p1++ = c;
blank = true;
}else if (blank) {
*p1++ = ' ';
blank = false;
}
}
//最后一个字符不要存空格
*p1--;*p1 = '\0';
}
bool judge01(char* str, int len) {
}
bool judge02(char* str, int len) {
char* p = str;
while (*p++)
;
p--; p--;//定位到末尾 两个!!!
char* p1 = str;
//排除首字母大写
/*putchar(*p);
putchar(*p1);*/
if ((*p - *p1) == ('z' - 'Z')|| *p == *p1) {
p--; p1++;
}
else {
return false;
}
while ((p != p1) && ((*p--) == (*p1++))) //指针往中间移动,且比较元素
;
//退出条件,指针相等或者者元素不相等
if (p-p1<=1) {
return true;
}
else {
return false;
}
}
int main(void) {
char str[MAX_NUM];
char re_str[MAX_NUM];
printf("Enter a message: ");
read_char(str, MAX_NUM);
printf("%s\n", str);
judge01(str, MAX_NUM) ? printf("Palindrome\n") : printf("Not a palindrome\n");
judge02(str, MAX_NUM)? printf("Palindrome\n") : printf("Not a palindrome\n");
return 0;
}
答案:
答案思路——完全输入——比较(只比较字母)
while (i < j && !isalpha(message[i])) isalpha,标准库函数,是否是字母
if (tolower(message[i]) != tolower(message[j])) return false; tolower,toupper标准库函数,转换成小写字母
(a) #include <stdio.h> #include <stdbool.h> #include <ctype.h> #define MAXLINE 128 bool is_palindrome(char message[], int n) { int i = 0, j = n - 1; while (i < j) { while (i < j && !isalpha(message[i])) { i++; } // i == j || message[i] is a alphabet while (i < j && !isalpha(message[j])) { j--; } // i == j || message[j] is a alphabet if (tolower(message[i]) != tolower(message[j])) return false; i++; j--; } return true; } int main(void) { printf("Enter a message: "); char message[MAXLINE]; int n = 0; char c; while (n < MAXLINE && (c = getchar()) != '\n') { message[n] = c; n++; } // n == MAXLINE || c == '\n' if (is_palindrome(message, n)) { printf("Palindrome\n"); } else { printf("Not a palindrome\n"); } return 0; } (b) #include <stdio.h> #include <stdbool.h> #include <ctype.h> #define MAXLINE 128 bool is_palindrome(char* start, char* end) { while (start < end) { while (start < end && !isalpha(*start)) { start++; } // i == j || message[i] is a alphabet while (start < end && !isalpha(*end)) { end--; } // i == j || message[j] is a alphabet if (tolower(*start) != tolower(*end)) return false; start++; end--; } return true; } int main(void) { printf("Enter a message: "); char message[MAXLINE]; char* p = message; char c; while (p < message + MAXLINE && (c = getchar()) != '\n') { *p++ = c; } // p == message + MAXLINE || c == '\n' // p 指向最后一个字符后面 if (is_palindrome(message, p - 1)) { printf("Palindrome\n"); } else { printf("Not a palindrome\n"); } return 0; }
作业3 比较单词
编写程序找出一组单词中最小单词和最大单词。当用户输入4个字母的单词时,程序停止读入。假设所有单词都不超过20个字母。程序会话如下:
Enter word: dog
Enter word: zebra
Enter word: rabbit
Enter word: catfish
Enter word: walrus
Enter word: cat
Enter word: fish
Smallest word: cat
Largest word: zebra
提示:使用两个名为 smallest_word 和 largest_word 的字符串来分别记录最小单词和最大单词。
用户每输入一个新单词,都要用 strcmp 把它与 smallest_word 和 largest_word 进行比较。
用 strlen 函数判断用户是否输入了 4 个字母的单词。
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NUM 21
int main(void) {
char blank[MAX_NUM] = "";
char arr[MAX_NUM];
char max[MAX_NUM]="";
char min[MAX_NUM]="";
char c; char* p ; bool first = true;
while (1) {
printf("Enter word: ");
p = arr;//初始化p
strcpy(arr, blank);
while ((c = getchar()) == ' ')
;
*p++ = c;
while ((c = getchar()) != '\n') {
*p++ = c;
}
*p = '\0';
if (strlen(arr) == 4) {
break;
}
if (first) {
strcpy(max, arr);
strcpy(min, arr);
first = false;
}
if(strcmp(arr,max)>0){
strcpy(max, arr);
}else if (strcmp(arr, min)<0) {
strcpy(min, blank);
strcpy(min, arr);
}
}
printf("Largest word: %s\n", max);
printf("Smallest word: %s\n", min);
return 0;
}
答案:
字符串读写,不要用getchar 和 putchar了
scanf("%s",word) 的匹配规则
忽略前置空白字符,读取字符,填入字符数组,遇到空白字符结束——适合空白字符分割的单词读入
不检查数组越界,记得检查
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #define MAXWORD 21 int main(void) { char smallest_word[MAXWORD]; char largest_word[MAXWORD]; char word[MAXWORD]; // 用第一个单词初始化 smallest_word 和 largest_word printf("Enter word: "); scanf("%s", word); strcpy(smallest_word, word); strcpy(largest_word, word); while (strlen(word) != 4) { printf("Enter word: "); scanf("%s", word); if (strcmp(word, smallest_word) < 0) { strcpy(smallest_word, word); } else if (strcmp(word, largest_word) > 0) { strcpy(largest_word, word); } }; printf("\nSmallest word: %s\n", smallest_word); printf("Largest word: %s\n", largest_word); return 0; }
619作业1:搜索字符串末尾
编写下面的函数:
void remove_filename(char* url);
url 指向一个包含以文件名结尾的 URL 字符串,例如 "http://www.knking.com/index.html"。函数需要移除文件名和前面的斜杠。(在上面的例子中,结果为 "http://www.knking.com")。要求在函数中使用 "搜索字符串末尾" 的惯用法。
提示:把字符串中的最后一个斜杠替换为空字符。
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAXNUM 100
void remove_filename(char* url) {
fgets(url, MAXNUM, stdin);
char* p = url;
int count = 0;
while (count != 3 && p < url + MAXNUM && *p) {
if (*p == '/') {
count++;
}
p++;
}//break *p=='/'
p--;
*p = '\0';
puts(url);
}
int main(void) {
char str[MAXNUM] = "";
remove_filename(str);
return 0;
}
答案:
多种情况下,是找到最后一个P,而不是限制第三个
也不需要计数,每次*URL==‘/’的时候,用指针P记录地址,遍历完整之后,指针P记录的就是最后一个‘/’的地址,修改成‘\0'#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void remove_filename(char* url) { char* p = url; // 搜索最后一个 '/' while (*url) { if (*url == '/') { p = url; } url++; } if (*p == '/') { *p = '\0'; } } int main(void) { char url[] = "http://www.knking.com/index.html"; remove_filename(url); puts(url); return 0; }
619作业2:自己版本的 strlen
size_t my_strlen(const char* s);
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAXNUM 100
size_t my_strlen(const char* s) {
char* p = s; size_t num = 0;
while (*p) {
num++;
p++;
}
return num;
}
int main(void) {
char s[] = "i love xixi";
printf("my_strlen is % d\n",my_strlen(s));
printf("strlen is % d\n", strlen(s));
return 0;
}
619作业3:自己版本的 strcpy
char* my_strcpy(char* s1, const char* s2);
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAXNUM 100
char* my_strcpy(char* s1, const char* s2) {
char* p1 = s1;
char* p2 = s2;
while (*p1++ = *p2++)
;
return s1;
}
int main(void) {
char s[MAXNUM] = "i love xixi";
char s2[MAXNUM] = "";
char s3[MAXNUM] = "";
my_strcpy(s2, s);
strcpy(s3, s);
puts(s2); puts(s3);
return 0;
}
619作业4:自己版本的 strcat
char* my_strcat(char* s1, const char* s2);
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAXNUM 100
char* my_strcat(char* s1, const char* s2) {
int* p = s1;
int* p1 = s2;
while (*p) {
p++;
}
while (*p++ = *p1++)
;
*p = '\0';
return s1;
}
int main(void) {
char s[MAXNUM] = " i love xixi";
char s1[MAXNUM] = "i love panpan ";
char s2[MAXNUM] = "huasheng and";
my_strcat(s2, s); //huasheng and i love xixi
strcat(s1, s); //i love panpan i love xixi
puts(s2); puts(s1);
return 0;
}
619作业5:自己版本的 strcmp
int my_strcmp(const char* s1, const char* s2);
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAXNUM 100
int my_strcmp(const char* s1, const char* s2) {
char* p = s1; char* p1 = s2;
while (*p++ == *p1++)
;
return *(p--) - *(p1--);
}
int main(void) {
char s[MAXNUM] = "i love xixi";
char s1[MAXNUM] = "i love panpan ";
my_strcmp(s, s1) > 0 ? printf("i love xixi is big\n") : printf("i love panpan is big\n");
strcmp(s, s1) > 0 ? printf("i love xixi is big\n") : printf("i love panpan is big\n");
return 0;
}