C - 函数未计算给定字符的正确数量

标签 c counting

如标题所述,我的函数没有计算给定字符串中正确的操作系统字符数。

函数是这个:

   void contar(char **texto, int *quantidade, int N)
 {
    int i, j, aux;

    for(i=0;i<N;i++)
    {
        for(j=0;texto[i][j]!='\0';j++)
        {
            aux = (int) texto[i][j];            
            /* If upper case */
            if(64 < aux && aux < 91)
            {
                aux = aux - 65;
                quantidade[aux]++;
            }
            /* If lower case */
            else if(96 < aux && aux < 123)
            {
                aux = aux - 71;
                quantidade[aux]++;
            }
        }
    }
    for(i=0;i<52;i++)
    {
        printf("\n i-%d  %d\n", i, quantidade[i]);
    }
 }

我的目标是:取出这个字符,根据ASCII表检查他的编号。如果数字代表大写字符,我将其减去 65 并将其用作 vector 的索引,并在该位置增加 vector 。如果它是小写字符,我将其减去 71,因为最后一个大写字符是 Z,它对应于 90。而“a”对应于 97。所以 90 - 65 = 25 和 97 - 65 = 32,如下我不想在 vector 中留下这个间隙,我喜欢 97 - 65 - 6。

发生的情况是,对于某些字符,该函数会少计算 1 个字符。 例如,在下面的文本中,该函数仅计算 5 个“A”,而实际上有 6 个。

Duvidas Frequentes E um grau do ensino superior obtido em cursos de Graduacao, ministrados pela Universidade, destinados a alunos que tenham concluido o ensino medio ou equivalente. A Unicamp oferece cursos de Graduacao em diferentes areas do conhecimento. A estrutura de ensino e pesquisa da Unicamp esta, em sua maior parte, no campus de Barao Geraldo, em Campinas. Em Piracicaba funciona a Faculdade de Odontologia de Piracicaba (FOP); em Limeira, a Faculdade de Tecnologia (FT) e Faculdade de Ciencias Aplicadas (FCA); em Paulinia, o Centro de Pesquisas Quimicas, Biologicas e Agricolas (CPQBA); em Sumare, o Hospital Estadual; e, em Hortolandia, o Hospital Mario Covas.

其余代码如下:

 #include <stdio.h>
 #include <stdlib.h>

 void encriptar(char **texto, int **ascii, int *quantidade, int *prioridade, int N);
 void matriz_ascii(char **texto, int **ascii, int N);
 void ordenar(int *quantidade, int *prioridade);
 void contar(char **texto, int *quantidade, int N);
 int checarMaior(int *quantidade, int i);
 void troca(int **ascii, int *prioridade, int N);

 int main()
 {
    int N, i, j, quantidade[52], prioridade[26], **ascii;
    char **texto;

    for(i=0;i<52;i++)
    {
        quantidade[i] = 0;
    }

    for(i=0;i<26;i++)
    {
        prioridade[i] = 0;
    }
    scanf("%d", &N);

    setbuf(stdin, 0);

    texto = malloc(N * sizeof(char *));
    ascii = malloc(N * sizeof(char *));

    for(i=0;i<N;i++)
    {
        texto[i] = malloc(501 * sizeof(char));
        ascii[i] = malloc(501 * sizeof(char));
    }

    for(i=0;i<N;i++)
    {
        fgets(texto[i], 501, stdin);
    }

    encriptar(texto, ascii, quantidade, prioridade, N);

    for(i=0;i<N;i++)
    {
        for(j=0;texto[i][j];j++)
        {
            texto[i][j] = (char) ascii[i][j];
        }
    }

    printf("\n");

    for(i=0;i<N;i++)
    {
        printf("%s", texto[i]);
    }

    printf("\n");

    for(i=0;i<26;i++)
    {
        printf("%d ", prioridade[i]);
    }

    printf("\n");       

    return 0;
 }

 void encriptar(char **texto, int **ascii, int *quantidade, int *prioridade, int N)
 {
    matriz_ascii(texto, ascii, N);

    contar(texto, quantidade, N);

    ordenar(quantidade, prioridade);

    troca(ascii, prioridade, N);
 }

 void matriz_ascii(char **texto, int **ascii, int N)
 {
    int i, j;

    for(i=0;i<N;i++)
    {
        for(j=0;texto[i][j]!='\0';j++)
        {
            ascii[i][j] = (int) texto[i][j];
        }
    }
 }

 void contar(char **texto, int *quantidade, int N)
 {
    int i, j, aux;

    for(i=0;i<N;i++)
    {
        for(j=0;texto[i][j]!=0;j++)
        {
            /*aux = (int) texto[i][j];
            printf("%d ", aux); */      
            /* Se for maiusculo */
            if(65 <= texto[i][j] && texto[i][j] <= 90)
            {
                aux = texto[i][j] - 65;
                quantidade[aux]++;
            }
            /* Se for minusculo */
            else if(97 <= texto[i][j] && texto[i][j] <= 122)
            {
                aux = texto[i][j] - 71;
                quantidade[aux]++;
            }
        }
        printf("\n");
    }
    /*for(i=0;i<52;i++)
    {
        printf("\n i-%d  %d\n", i, quantidade[i]);
    }*/
 }

 void ordenar(int *quantidade, int *prioridade)
 {
    int i, i_maior;
    for(i=0;i<26;i++)
    {
        quantidade[i] += quantidade[i+26];
    }

    for(i=0;i<26;i++)
    {
        i_maior = checarMaior(quantidade, 0);
        quantidade[i_maior] = -1;
        prioridade[i] = i_maior;
    }

 }

 int checarMaior(int *quantidade, int i)
 {
    int i_maior = i, maior = quantidade[i];

    for(i=i+1;i<26;i++)
    {
        if(quantidade[i] > maior)
        {
            maior = quantidade[i];
            i_maior = i;
        }
        else if(quantidade[i] == maior)
        {
            if(i < i_maior)
            {
                i_maior = i;
            }
        }
    }

    return i_maior;
 }

 void troca(int **ascii, int *prioridade, int N)
 {
    int i, j, i_aux, i_num, aux, valor = -1;
    for(i=0;i<N;i++)
    {
        for(j=0;ascii[i][j];j++)
        {   
            aux = ascii[i][j];
            /* Se for maiusculo */
            if(64 < aux && aux < 91)
            {
                aux = aux - 65;
                valor = 1;
            }
            /* Se for minusculo */
            else if(96 < aux && aux < 123)
            {
                aux = aux - 97;
                valor = 0;
            }
            else
            {
                valor = -1;
            }

            if(valor != -1)
            {
                for(i_aux=0;i_aux<26;i_aux++)
                {
                    if(prioridade[i_aux] == aux)
                    {
                        i_num = i_aux;
                    }
                }
                if(i_num % 2 == 0)
                    aux = prioridade[i_num+1];
                else
                    aux = prioridade[i_num-1];

                if(valor == 1)
                    ascii[i][j] = aux + 65;
                else if(valor == 0)
                    ascii[i][j] = aux +97;
            }
        }   
    }
 }

对我做错了什么有什么想法吗?

提前致谢!

最佳答案

quantidade 函数看起来没问题。但是 matriz_ascii 中的这个循环有一个问题:

for(i=0;i<N;i++)
    {
        for(j=0;texto[i][j]!='\0';j++)
        {
            ascii[i][j] = (int) texto[i][j];
        }
    }

这不会复制空终止符。但稍后,在 troca 中,您将有一个循环运行直到 ascii[i][j] == 0;。该循环将从复制值的末尾开始运行,直到它们碰巧在其他内存中遇到 0,这很糟糕。

正如您在评论中指出的那样,您也malloc错误的空间量(在两个不同的行上)。您可以通过使用以下惯用语来避免这种情况:

texto = malloc(N * sizeof *texto);
ascii = malloc(N * sizeof *ascii);

for(i=0;i<N;i++)
{
    texto[i] = calloc(501, sizeof *texto[i]);
    ascii[i] = calloc(501, sizeof *ascii[i]);
}

我使用 calloc 的原因是,如果您的 fgets 行失败(例如由于输入结束),则您的数组包含空白字符串,您的代码可以正确处理该字符串。否则,短输入文件将导致您的代码在未初始化的内存上运行。

您可以采取其他措施来使代码更具可读性和健壮性:

  • 65 等魔数(Magic Number)替换为 'A'
  • 将设置为 0 的循环替换为初始化为 = { 0 };calloc
  • 检查 malloc 是否返回 NULL

此外,在此处发布之前,您应该付出更多努力进行调试。如果某些东西不起作用,则更改代码以添加额外的调试输出(或使用调试器),直到您准确地找出哪个小部分导致程序从好到坏。您也可以尝试 valgrind。

关于C - 函数未计算给定字符的正确数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23621020/

相关文章:

javascript - 可以关联的数字的基数是否有限制?

c - malloc分配的内存有边界吗?

ios - 在 Objective-C 中将两个 uint8_t 转换/组合为 int16_t

c - 如何在 C/C++ 中读取文件时搜索换行符

c++ - 如何在 gcc 中禁用尾调用优化

python - 如何计算numpy数组中元素的频率?

计算每个唯一数字的出现次数 : algorithm almost works

python - 仍然对引用计数感到困惑

r - 计算不同客户之间的常见元素集

c - 使用 GNU C 正则表达式库的字符串正则表达式