首页 > 代码库 > 7.82 指针练习之,输入任意个谚语,将它们存入执行时期分配的内存中,然后由短到长地排序

7.82 指针练习之,输入任意个谚语,将它们存入执行时期分配的内存中,然后由短到长地排序

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define BUFFER_LEN 5 //初始化输入缓冲长度
#define BUFFER_LEN_INCR 3//缓冲长度增长量
#define CAPACITY_INCR 2 //对于要输入的谚语的增长容量

int main(void)
{
    char **pProverbs=NULL; //指向谚语字符串的指针
    char **temp=NULL; //临时指针
    size_t *pLengths =NULL; //谚语长度的指针
    size_t *ptemplengths =NULL;//临时长度指针
    int capacity = 0; //能够存储谚语的数目
    int count =0; //读入谚语的数目
    char *pstart =NULL; //指向缓冲输入的开头指针
    char *pstr = NULL; //指向一个字符串的指针
    int buffer_length =BUFFER_LEN; //输入缓冲长度

    char *pbuffer = (char*) malloc(BUFFER_LEN);//初始化缓冲区的内存分配,注意,这是一维的数组
    if(!pbuffer)
    {
        printf("bullshit\n");
        exit(1);
    }
    
    pstart = pbuffer;//存储缓冲区的开头
    for(;;)
    {
        //1.确定存多少句谚语。
        //是否存满了容量
        if(count == capacity)
        {
            capacity += CAPACITY_INCR;//每次增加两个谚语容量
            temp = realloc(pProverbs,capacity*sizeof(char*));//重新开辟新内存给pProverbs,指定char*类型指针,数量为capacity
            if(!temp)
            {
                printf("bullshit!\n");
                exit(1);
            }
            pProverbs = temp;
            temp =NULL;

            ptemplengths = realloc(pLengths,capacity*sizeof(size_t));//
            if(!ptemplengths)
            {
                printf("bullshit!\n");
                exit(1);
            }
            pLengths = ptemplengths;
            ptemplengths=NULL;
        }

        printf("Enter a proverb and press Enter, or just press Enter to end:\n");
        
        //2.确定每句谚语的输入存到动态分配的内存中
        //阅读设备输入的谚语了
        while((*pbuffer++ = getchar())!=\n)//一维的数组元素录入
        {
            if(pbuffer-pstart == buffer_length)
            {
                buffer_length += BUFFER_LEN_INCR;  //增加缓冲长度
                pstr = realloc(pstart,buffer_length);//重新分配新缓冲的内存
                if(!pstr)
                {
                    printf("bullshit!\n");
                    exit(1);
                }
                
                //新内存包含了当前谚语文本,但能够成为一个与pstart不相同的地址
                //我们一定要重置pbuffer的指针,到同样相关地址的新内存。
                //正如它在旧内存,pstart应该指向新缓冲
                pbuffer =pstr+(pbuffer-pstart);//新内存中下一个位置的地址
                pstart = pstr;
                pstr =NULL;
            }
        }
        
        //3.如果是空的就退出。
        if((pbuffer-pstart)<2)
            break;
        
        //4.把当前输入好的谚语字符串存入二维元素中。为何+1
        *(pbuffer-1)  = \0;
        pbuffer = pstart;
        *(pLengths + count) = strnlen_s(pbuffer,buffer_length);//例如你输入a,长度就是1
        //printf("%d\n",*(pLengths + count));
        if(!(*(pProverbs+count)=(char*)malloc(*(pLengths+count)+1)))//但这里开辟空间就要预留\0字符
        {
            printf("bullsht!\n");
            exit(1);
        }
        strcpy_s(*(pProverbs+count),*(pLengths+count)+1,pbuffer);
        ++count;
    }

    size_t length = 0;
    for(size_t i = 0;i<count-2;++i)
    {
        for(size_t j = i+1;j<count-1;j++)
        {
            if(*(pLengths+i)>*(pLengths+j))
            {
                pstr = *(pProverbs+i);
                *(pProverbs+i) = *(pProverbs+j);
                *(pProverbs+j) = pstr;

                length = *(pLengths+i);
                *(pLengths+i) = *(pLengths+j);
                *(pLengths +j) = length ;
            }
        }
    }

    printf("\nAll:\n");
    for(size_t i = 0;i<count;++i)
    {
        printf("%s\n",*(pProverbs+i));
        free(*(pProverbs+i));
        *(pProverbs+i)=NULL;
    }
    
    free(pProverbs);
    free(pstart);
    free(pLengths);
}

 

7.82 指针练习之,输入任意个谚语,将它们存入执行时期分配的内存中,然后由短到长地排序