题目:
将一句话的单词进行倒置,标点不倒置。(字符数组长度不超过100)
比如:I like beijing.
经过函数后变为:beijing. like I
=========================================================================
思路:
总体思路:
(可以把两步顺序调换)
第一步: 把 整个字符串 逆序
(知道 整个字符串 的首尾地址后,一对一对向整个字符串中间靠拢交换)
第二步:再逆序 每个单词
(知道 每个单词 的首尾地址后,一对一对向单词中间靠拢交换)
两步中逆序的方法是一样的,可以写一个相应的 自定义函数reverse
补充知识点一:gets()
读取一个 字符串 ,即使中间有空格
gets(arr); -- 把读取到的字符串 放进 字符串数组arr中
(编译器可能会觉得该函数不安全而报警告,因为读取的字符串放进数组后可能会导致数组越界,可能会报错爆红,但还是可以用的)
补充知识点二:fgets()
可以使用 fgets()函数 替代 gets()函数
fgets(arr, 100, stdin);
函数参数:
arr:把读取的字符串放进字符数组arr中
100:获取字符串最大字符数,这里设置为100
stdin:输入方式,stdin 为 键盘输入
(因为指定了获取的字符个数,所以不用担心数组越界,也就不会报警告)
第一步:
完成 逆序自定义函数reverse 编写:
(1).
函数参数:
char* left -- 左元素位置
char* right -- 右元素位置
(2).
使用 while循环,left < right 就继续循环逆序,因为此时数组还有数,
使用临时变量tmp,进行数组元素调换,
调换一次后就调整一次左右位置
实现代码:
#include <stdio.h>//逆序自定义函数 reverse: void reverse(char* left, char* right) {//使用while循环:while (left < right)//左小于右,说明中间还有值且没有指向一个字符,继续逆序{//使用临时变量tmp进行逆序:char tmp = *left;*left = *right;*right = tmp;//调换后调整左右位置left++;right--;} }int main() {}
实现图片:
第二步:
主函数:
(1). 定义字符数组,数组长度不超过100,那就设置为101
(2). 使用 gets(arr); 把读取到的字符串 放进 字符串数组arr中
(3). 求字符串长度 -- strlen(arr); 需要头文件<string.h>
(4). 使用 逆序自定义函数reverse 逆序 整个字符数组 ,
将整个数组arr的左右下标传给函数reverse即可
实现代码:
#include <stdio.h> #include <string.h>//逆序自定义函数 reverse: void reverse(char* left, char* right) {//使用while循环:while (left < right)//左小于右,说明中间还有值且没有指向一个字符,继续逆序{//使用临时变量tmp进行逆序:char tmp = *left;*left = *right;*right = tmp;//调换后调整左右位置left++;right--;} }int main() {//定义字符数组:char arr[101];//使用 gets(arr) 获取字符串gets(arr);//求字符串长度:int len = strlen(arr);//strlen 不会把 \0 计算进去,找到 \0 就停了//需要头文件:<string.h>//逆序整个字符串:reverse(arr, arr + len - 1); //调用自定义逆序函数//函数参数:数组首地址(左指针)、最后一个字符的地址(右指针)//arr+len-1:首地址 + 数组长度 - 1 --> 最后一个字符的地址 }
实现图片:
第三步:
主函数:逆序整个单词:
(1). 定义单词的 起始 和 尾部 位置:
char* start; -- 单词起始位置
char* cur; -- 单词尾部位置
(2). 使用 while循环 循环查找单词并逆序单词,
*cur 单词尾部还没有到结束符 '\0' 就继续找单词
(3). 内嵌 while循环 ,调整 cur 单词尾部位置:
*cur 单词尾部还没有到 空格(每个单词间隔一个空格)
且
还没到结束符 '\0'
就 cur++ ,调整当前单词尾部位置
(4). 经过上一个步骤,找到了第一个单词(第一次while循环),
对该单词进行逆序:
调用 逆序函数reverse,
将该单词的首位(左右)位置传给reverse即可
(5). 调整 start 单词起始位置,到下一个单词的起始位置:
start = cur +1; -- cur + 1, 空格后的下一个位置就是下一个单词的起始位置
(6). 调整 cur 单词尾部位置,
先使用 if条件判断语句 调整到空格后一位,即单词起始位置,
再在下一次循环通过内嵌的 while循环 调整到该单词的尾部位置
实现代码:
#include <stdio.h> #include <string.h>//逆序自定义函数 reverse: void reverse(char* left, char* right) {//使用while循环:while (left < right)//左小于右,说明中间还有值且没有指向一个字符,继续逆序{//使用临时变量tmp进行逆序:char tmp = *left;*left = *right;*right = tmp;//调换后调整左右位置left++;right--;} }int main() {//定义字符数组:char arr[101];//使用 gets(arr) 获取字符串gets(arr);//求字符串长度:int len = strlen(arr);//strlen 不会把 \0 计算进去,找到 \0 就停了//需要头文件:<string.h>//逆序整个字符串:reverse(arr, arr + len - 1); //调用自定义逆序函数//函数参数:数组首地址(左指针)、最后一个字符的地址(右指针)//arr+len-1:首地址 + 数组长度 - 1 --> 最后一个字符的地址//逆序每个单词://定义 单词的 起始 和 尾部 位置:char* start = arr; //单词起始位置char* cur = arr; //单词尾部位置,后面再调整//使用 while循环 循环查找并逆序单词:while (*cur != '\0')//整个字符串还没结束,继续找单词{//内嵌 while循环 调整单词尾部位置cur:while (*cur != ' ' && *cur != '\0')//单词尾部未找到空格且还没有结束符就继续往后移一位{cur++;//往后移一位}//直到找到单词,此时在空格位置//找到单词后进行单词逆序:reverse(start, cur - 1);//因为单词尾部 cur 此时在 空格位置,//所以要在空格(或\0,最后一个单词)位置前-1//找下一个单词://调整start单词起始位置:start = cur + 1;//cur+1,空格后的下一个位置就是下一个单词的首地址//调整单词尾部位置:if (*cur == ' ')//只有是空格时才能跳过,\0不能再跳过了,不然就跳不出循环了{cur++;//调整下一个单词尾部位置到起始位置}}}
实现图片:
第四步:
两个逆序都完成后,进行打印
实现代码:
#include <stdio.h> #include <string.h>//逆序自定义函数 reverse: void reverse(char* left, char* right) {//使用while循环:while (left < right)//左小于右,说明中间还有值且没有指向一个字符,继续逆序{//使用临时变量tmp进行逆序:char tmp = *left;*left = *right;*right = tmp;//调换后调整左右位置left++;right--;} }int main() {//定义字符数组:char arr[101];//使用 gets(arr) 获取字符串gets(arr);//求字符串长度:int len = strlen(arr);//strlen 不会把 \0 计算进去,找到 \0 就停了//需要头文件:<string.h>//逆序整个字符串:reverse(arr, arr + len - 1); //调用自定义逆序函数//函数参数:数组首地址(左指针)、最后一个字符的地址(右指针)//arr+len-1:首地址 + 数组长度 - 1 --> 最后一个字符的地址//逆序每个单词://定义 单词的 起始 和 尾部 位置:char* start = arr; //单词起始位置char* cur = arr; //单词尾部位置,后面再调整//使用 while循环 循环查找并逆序单词:while (*cur != '\0')//整个字符串还没结束,继续找单词{//内嵌 while循环 调整单词尾部位置cur:while (*cur != ' ' && *cur != '\0')//单词尾部未找到空格且还没有结束符就继续往后移一位{cur++;//往后移一位}//直到找到单词,此时在空格位置//找到单词后进行单词逆序:reverse(start, cur - 1);//因为单词尾部 cur 此时在 空格位置,//所以要在空格(或\0,最后一个单词)位置前-1//找下一个单词://调整start单词起始位置:start = cur + 1;//cur+1,空格后的下一个位置就是下一个单词的首地址//调整单词尾部位置:if (*cur == ' ')//只有是空格时才能跳过,\0不能再跳过了,不然就跳不出循环了{cur++;//调整下一个单词尾部位置到起始位置}}//两个逆序都完成后,进行打印:printf("%s", arr);}
实现图片:
最终代码和实现效果
最终代码:
#include <stdio.h> #include <string.h>//逆序自定义函数 reverse: void reverse(char* left, char* right) {//使用while循环:while (left < right)//左小于右,说明中间还有值且没有指向一个字符,继续逆序{//使用临时变量tmp进行逆序:char tmp = *left;*left = *right;*right = tmp;//调换后调整左右位置left++;right--;} }int main() {//定义字符数组:char arr[101];//使用 gets(arr) 获取字符串gets(arr);//求字符串长度:int len = strlen(arr);//strlen 不会把 \0 计算进去,找到 \0 就停了//需要头文件:<string.h>//逆序整个字符串:reverse(arr, arr + len - 1); //调用自定义逆序函数//函数参数:数组首地址(左指针)、最后一个字符的地址(右指针)//arr+len-1:首地址 + 数组长度 - 1 --> 最后一个字符的地址//逆序每个单词://定义 单词的 起始 和 尾部 位置:char* start = arr; //单词起始位置char* cur = arr; //单词尾部位置,后面再调整//使用 while循环 循环查找并逆序单词:while (*cur != '\0')//整个字符串还没结束,继续找单词{//内嵌 while循环 调整单词尾部位置cur:while (*cur != ' ' && *cur != '\0')//单词尾部未找到空格且还没有结束符就继续往后移一位{cur++;//往后移一位}//直到找到单词,此时在空格位置//找到单词后进行单词逆序:reverse(start, cur - 1);//因为单词尾部 cur 此时在 空格位置,//所以要在空格(或\0,最后一个单词)位置前-1//找下一个单词://调整start单词起始位置:start = cur + 1;//cur+1,空格后的下一个位置就是下一个单词的首地址//调整单词尾部位置:if (*cur == ' ')//只有是空格时才能跳过,\0不能再跳过了,不然就跳不出循环了{cur++;//调整下一个单词尾部位置到起始位置}}//两个逆序都完成后,进行打印:printf("%s", arr);}
实现效果: