【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 **str2swap方法时,传入的应该是指针数组中的指针变量的地址,如果写成如下,则不会正常进行交换:
    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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值