【C语言】字符串数组按字典升序
在使用C语言操作字符串时,容易出现各种各样的错误;本文强调 字符指针数组要如何正确使用,尽量绕开不必要的错误,其他关于C语言字符串的操作参考
代码参考
- C语言指针数组初始化
- C语言交换字符指针内容的两种方式
一、使用strcpy深拷贝实现字符串交换
实现代码如下:
#include <stdio.h>
#include <string.h>
#include <iostream>
#define MAXLEN 1000
using namespace std;
//字符串按字典排序
void arr_sort(char *arr[], int len){
int i,j;
//插入排序
for(i = 1; i < len; ++i){
int index = 0;
for(j = i; j > 0; --j){
if(strcmp(arr[j - 1], arr[j]) > 0){
// char *temp = arr[j]; //temp只是个指针变量,只是将temp指针指向了arr[j]的地址,并没有将arr[j]中的内容深拷贝到temp中
char temp[MAXLEN];
strcpy(temp,arr[j]);
strcpy(arr[j], arr[j-1]);
strcpy(arr[j-1], temp);
}
}
}
}
int main()
{
int num,i;
char *arr[num]; //字符串数组
char str[MAXLEN]; //输入的字符串
scanf("%d",&num);
printf("输入%d个单词\n",num);
for(i = 0; i < num; ++i){
arr[i] = (char *) malloc(sizeof(char) * MAXLEN); //如果未给arr[i]分配空间,scanf会报错:segmentation fault
scanf("%s",arr[i]);
}
int j;
cout << "排序前:" << endl;
for(i = 0; i < num; ++i){
cout << arr[i] << endl;
}
arr_sort(arr,num);
cout << "排序后:" << endl;
for(i = 0; i < num; ++i){
cout << arr[i] << endl;
}
return 0;
}
输出结果:
3
输入3个单词
peach
banana
apple
排序前:
peach
banana
apple
交换前peach banana apple 交换后banana peach apple
交换前banana peach apple 交换后banana apple peach
交换前banana apple peach 交换后apple banana peach
排序后:
apple
banana
peach
注意要点:
- 在定义字符指针数组(
char *arr[num]
) 时,如果未进行初始化,数组中的指针指向的是未知的内存空间;如果使用scanf("%s",arr[i])
会报错,原因是指针所指向的空间没有访问权限。解决方法是使用malloc
函数为arr[i]
分配存储空间。 - 在进行字符串交换时,可以通过
strcpy
实现字符串的深拷贝,下面比较深拷贝和浅拷贝://浅拷贝 char *temp = arr[j]; //temp只是个指针变量,只是将temp指针指向了arr[j]的地址,并没有将arr[j]中的内容深拷贝到temp中 //深拷贝 char temp[MAXLEN]; strcpy(temp,arr[j]);
二、交换字符指针数组中的指针位置,实现字符串交换
实现代码如下:感谢该问答
#include <stdio.h>
#include <string.h>
#include <iostream>
#define MAXLEN 1000
using namespace std;
//字符交换(错误)
void str_swap(char *str1, char *str2){
char temp = *str1; //获取str1字符串的第一个字符, 等价于char temp; temp = str1; 此时的temp指向了str1的首元素地址
*str1 = *str2; //字符交换
*str2 = temp;
}
//字符串交换
void str_swap1(char **str1, char **str2){
char *temp;
temp = *str1; //此时temp指向了*str1指针变量地址
*str1 = *str2; //形参中**str1是指向*str1指针的指针,*str1指针变量地址修改成了*str2指针变量地址
*str2 = temp; //形参中**str2是指向*str2指针的指针,*str2指针变量地址修改成了temp指针变量地址
}
//字符串按字典排序
void arr_sort(char *arr[], int len){
int i,j;
//插入排序
for(i = 1; i < len; ++i){
int index = 0;
for(j = i; j > 0; --j){
if(strcmp(arr[j - 1], arr[j]) > 0){
// str_swap(arr[j - 1],arr[j]);
int k = 0;
cout << "交换前";
for(k = 0; k < len; ++k){
cout << arr[k] << " ";
}
//char *temp = arr[j - 1];
//char *temp1 = arr[j];
//str_swap1(&temp,&temp1); //不应该传入新定义的指针变量的地址,而是要传入指针数组中的指针变量地址
//printf(" swap: %s, %s",temp,temp1);
str_swap1(&arr[j - 1],&arr[j]);
cout << "交换后";
for(k = 0; k < len; ++k){
cout << arr[k] << " ";
}
cout << endl;
}
}
}
}
int main()
{
int num,i;
char *arr[num]; //字符串数组
char str[MAXLEN]; //输入的字符串
scanf("%d",&num);
printf("输入%d个单词\n",num);
for(i = 0; i < num; ++i){
arr[i] = (char *) malloc(sizeof(char) * MAXLEN); //如果未给arr[i]分配空间,scanf会报错:segmentation fault
scanf("%s",arr[i]);
}
// printf("输入字符串\n");
// scanf("%s",str);
int j;
cout << "排序前:" << endl;
for(i = 0; i < num; ++i){
cout << arr[i] << endl;
}
arr_sort(arr,num);
cout << "排序后:" << endl;
for(i = 0; i < num; ++i){
cout << arr[i] << endl;
}
return 0;
}
输出结果:
3
输入3个单词
peach
banana
apple
排序前:
peach
banana
apple
交换前peach banana apple 交换后banana peach apple
交换前banana peach apple 交换后banana apple peach
交换前banana apple peach 交换后apple banana peach
排序后:
apple
banana
peach
注意要点:
- 在使用
str_swap
时,形成应该是char **str1, char **str2
,用来接收指针变量的地址。如果写成如下代码,则无法实现字符串交换,只能实现首字符交换:
输出结果void str_swap(char *str1, char *str2){ char temp = *str1; //获取str1字符串的第一个字符, 等价于char temp; temp = str1; 此时的temp指向了str1的首元素地址 *str1 = *str2; //字符交换 *str2 = temp; } void arr_sort(char *arr[], int len){ ... str_swap(arr[j - 1],arr[j]); ... }
3 输入3个单词 peach banana apple 排序前: peach banana apple 交换前beach panana apple 交换后beach panana apple 交换前beach aanana ppple 交换后beach aanana ppple 交换前aeach banana ppple 交换后aeach banana ppple 排序后: aeach banana ppple
- 在使用
char **str1, char **str2
的swap
方法时,传入的应该是指针数组中的指针变量的地址,如果写成如下,则不会正常进行交换:
输出结果:char *temp = arr[j - 1]; char *temp1 = arr[j]; str_swap1(&temp,&temp1); //传入指针变量的地址 printf(" swap: %s, %s",temp,temp1);
主要原因是上面的代码是对新定义的指针变量进行交换,而不是对指针数组中的指针变量进行交换,所以应传入指针数组中指针变量的地址,即3 输入3个单词 peach banana apple 排序前: peach banana apple 交换前peach banana apple swap: banana, peach 交换后peach banana apple 交换前peach banana apple swap: apple, banana 交换后peach banana apple 交换前peach banana apple swap: banana, peach 交换后peach banana apple 排序后: peach banana apple
&arr[j]
,&arr[j-1]
。