小哥哥咯 2018-05-08 00:24 采纳率: 100%
浏览 1297
已采纳

strcpy复制数组,程序异常奔溃

问题:解释一下我备注错误的地方为什么会使程序崩溃。
图片说明

开发IDE:codeblock17.12
链接:https://pan.baidu.com/s/1wwoP4v_Y5xYJtH7WZIWjdw 密码:gm87

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct element
{
    char *key;
    char *content;
}element;
char buf[2048]={0};
int get_elements(element **p,char * file_name)
{
    FILE * fp=fopen(file_name,"r");
    if(fp==NULL)
    {
        printf("打开文件失败!");
        return -1;
    }
    *p=(element*)malloc(sizeof(element));
    //char buf[2048]={0};
    int index=0;
    while(!feof(fp))
    {
        if(fgets(buf,sizeof(buf),fp)!=NULL)
        {
            (*p)[index].key=(char *)calloc(strlen(buf),sizeof(char));
            //strcpy((*p)[index].key,buf);//错误
            //strncpy((*p)[index].key,buf,strlen(buf));//错误
            //strcpy((*p)[index].key,&buf[0]);//错误
            strcpy((*p)[index].key,&buf[1]);//正确
            memset(buf,0,sizeof(buf));
        }
        if(fgets(buf,sizeof(buf),fp)!=NULL)
        {
            (*p)[index].content=(char *)calloc(strlen(buf),sizeof(char));
            //strcpy((*p)[index].content,buf);
            strcpy((*p)[index].content,&buf[6]);
            memset(buf,0,sizeof(buf));
        }
        printf("%s%s",(*p)[index].key,(*p)[index].content);

        index++;
        if((*p=(element*)realloc(*p,sizeof(element)*(index+1))) == NULL)
        {
            puts("error");
            return -1;
        }
        //memset(*p+index,0,sizeof(element));
    }
    fclose(fp);
    return index;
}
int search_element(element *p,int n,const char * key)
{
    int i=0;
    for(i=0;i<n;i++)
    {
        //if(strcmp(p[i].key,key)==0)//p[i].key[3]是'\n'字符,key[3]是'\0'字符
        if (strncmp(p[i].key, key, strlen(key)) == 0)
        {
            printf("%s",p[i].content);
            return 1;
        }
    }
    return -1;
}
//最好还是传指针的地址,不然就是野指针
int free_elements(element *p,int n)
{
    int i=0;
    for(i=0;i<n;i++)
    {
        if (p[i].key)
            free(p[i].key);
        if (p[i].content)
            free(p[i].content);
    }
    free(p);
    return 0;
}
int main()
{
    char file_name[]="dict.txt";
    element *p=NULL;
    int n = get_elements(&p,file_name);//将词典的内容读到内存
    search_element(p,n,"you");
    free_elements(p,n);
    return 0;
}

工程文件包:
链接:https://pan.baidu.com/s/1FfHerOqcVlGoP3-vSvXMIA 密码:b1gu

  • 写回答

4条回答

  • weixin_41475349 2018-05-08 01:59
    关注

    如果dict.txt是如下格式
    key:content
    可以做如下修改,代码中对于一些问题做出了建议,不对之处可以讨论
    #include
    #include
    #include
    typedef struct element
    {
    char *key;
    char *content;
    }element;

    char buf[2048]={0};
    int get_elements(element **p, char * file_name)
    {
    FILE * fp=fopen(file_name,"r");
    if(fp==NULL)
    {
    printf("打开文件失败!\n");
    return -1;
    }
    //*p=(element*)malloc(sizeof(element));
    //char buf[2048]={0};
    //index为string.h库中函数名,在包含该库的时候建议不使用
    int iIndex=0;
    while(!feof(fp))
    {
    //将内存分配放在这里,确保文件有内容可读的时候才分配内存
    if((*p=(element*)realloc(*p,sizeof(element)*(iIndex+1))) == NULL)
    {
    puts("error");
    return -1;
    }

        memset(buf,0,sizeof(buf));
        if(fgets(buf,sizeof(buf),fp)!=NULL) //读取文件一次,读取
        {
            (*p)[iIndex].key=(char *)calloc(strlen(buf),sizeof(char));
            //strcpy((*p)[index].key,buf);//错误
            //strncpy((*p)[index].key,buf,strlen(buf));//错误
            //strcpy((*p)[index].key,&buf[0]);//错误
            char *sepIndex = index(buf, ':');
            //查找key
            strncpy((*p)[iIndex].key, buf, sepIndex-buf);//strcpy很容易造成内存益处,建议使用strncpy
            //查找content
            (*p)[iIndex].content=(char *)calloc(strlen(buf),sizeof(char));
            strncpy((*p)[iIndex].content, sepIndex+1, strlen(sepIndex+1)); 
            sepIndex = NULL;
    

    /*
    if(fgets(buf,sizeof(buf),fp)!=NULL)
    {
    (*p)[index].content=(char *)calloc(strlen(buf),sizeof(char));
    //strcpy((*p)[index].content,buf);
    strcpy((*p)[index].content,&buf[6]);
    memset(buf,0,sizeof(buf));
    }
    */
    printf("%s: %s",(*p)[iIndex].key,(*p)[iIndex].content);
    }

        ++iIndex;
    

    /*
    //如果扩展内存放这里,意味着如果已经到了文件尾,还是继续分配了内存,造成资源浪费
    if((*p=(element*)realloc(*p,sizeof(element)*(iIndex+1))) == NULL)
    {
    puts("error");
    return -1;
    }
    //memset(*p+index,0,sizeof(element));
    /
    }
    fclose(fp);
    return iIndex;
    }
    int search_element(element *p,int n,const char * key)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    //if(strcmp(p[i].key,key)==0)//p[i].key[3]是'\n'字符,key[3]是'\0'字符
    if (strncmp(p[i].key, key, strlen(key)) == 0)
    {
    printf("%s",p[i].content);
    return 1;
    }
    }
    return -1;
    }
    //最好还是传指针的地址,不然就是野指针
    //这里你只释放了结构体内部的指针,对于结构体本身的指针并没有释放
    /

    int free_elements(element *p,int n)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    if (p[i].key)
    free(p[i].key);
    if (p[i].content)
    free(p[i].content);
    }
    free(p);
    return 0;
    }
    */
    int free_elements(element **p,int n)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    if ((*p)[i].key)
    free((*p)[i].key);
    if ((*p)[i].content)
    free((*p)[i].content);
    }
    free(*p);
    *p = NULL;
    return 0;
    }
    int main()
    {
    char file_name[]="dict.txt";
    element *p=NULL;
    int n = get_elements(&p,file_name);//将词典的内容读到内存
    search_element(p,n,"you");
    free_elements(&p,n);
    return 0;
    }

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 数学的三元一次方程求解
  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题