小哥哥咯 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条)

报告相同问题?

悬赏问题

  • ¥100 c语言,请帮蒟蒻看一个题
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)