题目:
将一句话的单词进行倒置,标点不倒置。(字符数组长度不超过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); }
实现效果: