风落平川 2023-11-05 23:27 采纳率: 96.7%
浏览 18
已结题

visual stdio编译器实现哈夫曼编码时拷贝字符函数报错

用strcpy会建议改成strcpy_s,用strcpy_s会说函数不接受两个参数且没有与参数列表匹配的重载函数strcpy_s函数实例。(属性是多字节字符集,不需要调。)

img

img


两种实现霍夫曼的方法放在这里,第一种是我自己写的。第二种是C站一篇博客里的。都出现了同样的问题。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
typedef struct {//哈夫曼树的每个叶子?结点的信息
    int weight;//权
    int parent, lchild, rchild;//该结点的父结点,左子结点,右子结点在数组中的编号
}HTNode, * Huffmantree;//结构体名
typedef char** HuffmanCode;
void Select(Huffmantree& HT, int i, int& s1, int& s2)//选择函数:用于从叶子结点开始构建哈夫曼树
{
    s1 = 0; s2 = 0;
    int min1 = 100; int min2 = 100;
    for (int k = 1; k <= i; k++)
    {
        if (HT[k].parent == 0)
        {
            if (HT[k].weight < min1)
            {
                min2 = min1;
                s2 = s1;
                min1 = HT[k].weight;
                s1 = k;
            }
            else if (HT[k].weight < min2)
            {
                min2 = HT[k].weight;
                s2 = k;
            }
        }
    }
}
void HuffmanCoding(Huffmantree& HT, HuffmanCode& HC, int* w, int n)//构建哈夫曼树并求哈夫曼编码
{
    if (n <= 1) return;
    int m = n * 2 - 1;//m为哈夫曼树的全部结点个数
    int i;//循环计数器
    Huffmantree p;
    HT = (Huffmantree)malloc((m + 1) * sizeof(HTNode));
    for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w)
    {
        p->weight = *w;
        p->parent = 0;
        p->lchild = 0;
        p->rchild = 0;
    }
    for (; i <= m; ++i, ++p)
    {
        p->weight = 0;
        p->parent = 0;
        p->lchild = 0;
        p->rchild = 0;
    }
    //建立哈夫曼树
    for (i = n + 1; i <= m; ++i)
    {
        int s1, s2;
        Select(HT, i - 1, s1, s2);
        HT[s1].parent = i;
        HT[s2].parent = i;
        HT[i].lchild = s1; HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }
    //从叶子到根逆向求哈夫曼编码
    HC = (HuffmanCode)malloc((static_cast<unsigned long long>(n) + 1) * sizeof(char*));
    char* cd{};
    cd = (char*)malloc(n * sizeof(char));//为cd申请n个存储空间
    cd[n - 1] = '\0';
    int c, f;
    for (i = 1; i <= n; ++i)
    {
        int start = n - 1;
        for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
            if (HT[f].lchild == c) cd[--start] = '0';
            else cd[--start] = '1';
        HC[i] = (char*)malloc((static_cast<unsigned long long>(n) - start) * sizeof(char));
        strcpy_s(HC[i], &cd[start]);
    }
    free(cd);
}
int main(void)
{
    int n = 8;
    int w[8] = { 5,29,7,8,14,23,3,11 };
    Huffmantree HT;
    HuffmanCode HC;
    int j;
    HuffmanCoding(HT, HC, w, n);
    printf("初始化如下\n");
    printf("     weight  parent  lchild rchild\n");
    for (j = 1; j <= 15; j++)
    {
        printf("HT[%d] %6d%6d%6d%6d\n", j, HT[j].weight, HT[j].parent, HT[j].lchild, HT[j].rchild);
    }
    printf("\n");
    printf("编码如下\n");
    for (j = 1; j <= 15; j++)
    {
        printf("HT[%d] %c\n", j, *HC[j]);
    }
    printf("\n");
    return 0;
}

#include <stdio.h>
#include <malloc.h>
#include <string.h>
 
typedef struct HTNode
{
    double weight;
    int parent;
    int lc, rc; 
}*HuffmanTree;
 
typedef char **HuffmanCode;
 
HuffmanTree initHuffmanTree(HuffmanTree& HT,int n)
{
    int i;
    int m = 2 * n - 1;
    HT = (HuffmanTree)malloc(sizeof(HTNode)*(m + 1));
    for(i = 0; i <= m; i++)
    {
        HT[i].lc = 0;
        HT[i].parent = 0;
        HT[i].rc = 0;
        HT[i].weight = 0;
    }
    return HT;
}void Select(HuffmanTree& HT, int n, int& min1, int& min2)
{
    int min;
    for (int i = 1; i <= n; i++)
    {
        if (HT[i].parent == 0)
        {
            min = i;
            break;
        }
    }
    for (int i = min + 1; i <= n; i++)
    {
        if (HT[i].parent == 0 && HT[i].weight < HT[min].weight)
            min = i;
    }
    min1 = min;
    for (int i = 1; i <= n; i++)
    {
        if (HT[i].parent == 0 && i != min1)
        {
            min = i;
            break;
        }
    }
    for (int i = min + 1; i <= n; i++)
    {
        if (HT[i].parent == 0 && HT[i].weight < HT[min].weight&&i != min1)
            min = i;
    }
    min2 = min;
}
 
void CreateHuff(HuffmanTree& HT,double* w, int n)
{
    int m = 2 * n - 1; 
    for (int i = 1; i <= n; i++)
    {
        HT[i].weight = w[i - 1];
    }
    for (int i = n + 1; i <= m; i++)
    {
        int min1, min2;
        Select(HT, i - 1, min1, min2);
        HT[i].weight = HT[min1].weight + HT[min2].weight; 
        HT[min1].parent = i; 
        HT[min2].parent = i;
        HT[i].lc = min1; 
        HT[i].rc = min2;
    }
    printf("Huffman is: \n");
    printf("subscript    weight     parent   lchild   rchild\n");
    printf("0                                  \n");
    for (int i = 1; i <= m; i++)
    {
        printf("%-4d         %-6.2lf      %-6d     %-6d   %-6d\n", i, HT[i].weight, HT[i].parent, HT[i].lc, HT[i].rc);
    }
    printf("\n");
}
void HuffCoding(HuffmanTree& HT, HuffmanCode& HC, int n)
{
    HC = (HuffmanCode)malloc(sizeof(char*)*(n + 1));
    char* code = (char*)malloc(sizeof(char)*n);
    code[n - 1] = '\0';
    for (int i = 1; i <= n; i++)
    {
        int start = n - 1; 
        int c = i; 
        int p = HT[c].parent; 
        while (p)
        {
            if (HT[p].lc == c) 
                code[--start] = '0';
            else
                code[--start] = '1';
            c = p;
            p = HT[c].parent; 
        }
        HC[i] = (char*)malloc(sizeof(char)*(n - start));
        strcpy(HC[i], &code[start]); 
    }
    free(code);
}
 
void test()
{
    int n = 0;
    printf("input the number of data: ");
    scanf("%d", &n);
    double* w = (double*)malloc(sizeof(double)*n);
    if (n >= 0)
    {
        printf("input the data: ");
        for (int i = 0; i < n; i++)
        {
            scanf("%lf", &w[i]);
        }
        HuffmanTree HT;
        HT = initHuffmanTree(HT,n);
        CreateHuff(HT, w, n); 
 
        HuffmanCode HC;
        HuffCoding(HT, HC, n); 
 
        for (int i = 1; i <= n; i++)
        {
            printf("The data %.2lf code is:  %s\n", HT[i].weight, HC[i]);
        }
        free(w);    
    }
    else
    {
        printf("malloc fail\n");
        return;
    }
}
 
int main(void)
{
    test();
    return 0;
}
/*————————————————
版权声明:本文为CSDN博主「C2395850595」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/C2395850595/article/details/125030617*/

  • 写回答

13条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-11-05 23:27
    关注

    引自强大而免费的微信小程序:皆我百晓生

    问题出在strcpy函数上。在Visual Studio编译器中,使用strcpy_s代替strcpy函数可以解决问题。strcpy_s是strcpy函数的安全版本,可以避免缓冲区溢出问题。但是strcpy_s的使用方式与strcpy不同,需要指定缓冲区大小。在你的代码中,由于参数列表不匹配,导致strcpy_s函数报错。要修复这个问题,你需要将strcpy_s函数的调用方式修改为正确的形式,如下所示:

    strcpy_s(HC[i], (n - start + 1), &code[start]);
    

    使用(n - start + 1)作为缓冲区的大小。这样就可以正确地使用strcpy_s函数了。请在你的代码中进行相应的修改,然后重新编译和运行,应该就不会报错了。

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

报告相同问题?

问题事件

  • 系统已结题 11月15日
  • 已采纳回答 11月7日
  • 创建了问题 11月5日

悬赏问题

  • ¥15 关于模型导入UNITY的.FBX: Check external application preferences.警告。
  • ¥15 气象网格数据与卫星轨道数据如何匹配
  • ¥100 java ee ssm项目 悬赏,感兴趣直接联系我
  • ¥15 微软账户问题不小心注销了好像
  • ¥15 x264库中预测模式字IPM、运动向量差MVD、量化后的DCT系数的位置
  • ¥15 curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused
  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题