简体   繁体   English

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

[英]C - Function is not counting the correct amount of given character

as said on the title, my function is not calculating the correct amount os characters in a given string. 如标题所述,我的函数无法计算给定字符串中正确数量的OS字符。

The function is this one: 功能是这个:

   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]);
    }
 }

My objective is: take the character, check his number according to the ASCII table. 我的目标是:提取字符,然后根据ASCII表检查其编号。 If the number represents an Upper Case Character, I subtract it by 65 and use it as the index of my vector and increment the vector in that position. 如果数字代表大写字符,我将其减去65,并将其用作向量的索引,并在该位置增加向量。 If it is a Lower Case Character, I subtract it by 71, because the last Upper Case Character is Z, which corresponds to 90. And the 'a' corresponds 97. So 90 - 65 = 25 and 97 - 65 = 32, as I dont wanna leave this gap in the vector, I do 97 - 65 - 6. 如果它是小写字母,我将其减去71,因为最后一个大写字母是Z,对应于90。而“ a”对应于97。所以90-65 = 25,而97-65 = 32,如我不想在向量中留下这个缺口,我做97-65-6。

What is happening is that, for certain characters, the function is counting 1 character less. 发生的情况是,对于某些字符,该功能减少了1个字符的计数。 For example, on the text below, the function counts only 5 'A', when there is actually 6. 例如,在下面的文本中,该功能实际上只计数为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. 坎普纳纳斯的Barao Geraldo校园内没有任何校园的人口普查大学。 Em Piracicaba funciona a Faculdade de Odontologia de Piracicaba (FOP); Em Piracicaba funciona a Faculdade de Odontologia de Piracicaba(FOP); em Limeira, a Faculdade de Tecnologia (FT) e Faculdade de Ciencias Aplicadas (FCA); 利米拉(Em Limeira),技术学院(FT)和公民科学学院(FCA); em Paulinia, o Centro de Pesquisas Quimicas, Biologicas e Agricolas (CPQBA); 保罗·波林尼亚,佩斯基萨斯·奎米卡斯中心,生物学家和农业部(CPQBA); em Sumare, o Hospital Estadual; em Sumare,医院医院; e, em Hortolandia, o Hospital Mario Covas. e,Hortolandia,o医院Mario Covas。

The rest of the code is the following one: 其余代码如下:

 #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;
            }
        }   
    }
 }

Any ideas of what I am doing wrong? 关于我在做什么错的任何想法?

Thanks in advance! 提前致谢!

The quantidade function seems OK. quantidade功能似乎还可以。 But this loop in matriz_ascii has a problem: 但是matriz_ascii中的此循环有一个问题:

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

This does not copy the null-terminator. 这不会复制空终止符。 But later on, in troca you have a loop that runs until ascii[i][j] == 0; 但是稍后,在troca您将运行一个循环,直到ascii[i][j] == 0; . That loops will run off the end of the copied values until they happen to come across a 0 in other memory, which is bad. 该循环将在复制值的末尾开始,直到碰巧遇到其他内存中的0 ,这很糟糕。

As you point out in comments, you malloc the wrong amount of space also (on two different lines). 正如您在注释中指出的那样,您也malloc了错误的空间量(在两行中)。 You could have avoided that by using this idiom: 您可以通过使用以下惯用语来避免这种情况:

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]);
}

The reason I use calloc is so that if your fgets lines fail (eg due to end of input) then your array contains blank strings, which your code handles correctly. 我使用calloc的原因是,如果您的fgets行失败(例如,由于输入结束),则您的数组包含空白字符串,您的代码可以正确处理该字符串。 Without that, a short input file would cause your code to operate on uninitialized memory. 否则,较短的输入文件将导致您的代码在未初始化的内存上运行。

Other things you can do to make your code more readable and robust: 您可以采取其他措施使代码更具可读性和健壮性:

  • replace magic numbers like 65 with 'A' , 'A'代替像65这样的魔术数字,
  • replace loops that set things to 0 with initialization to = { 0 }; 用初始化为= { 0 };替换将事物设置为0循环= { 0 }; , or calloc calloc
  • Check that malloc does not return NULL . 检查malloc不返回NULL

Also you should make more of an effort to debug before posting on here. 另外,在此发布之前,您应该花更多的精力进行调试。 If something is not working, then change your code to add extra debugging output (or use a debugger) until you find out exactly which little piece is causing the program to go from good to bad. 如果某些事情不起作用,则更改代码以添加额外的调试输出(或使用调试器),直到您确切地找出导致程序从好到坏的小片段为止。 Also you can try valgrind. 您也可以尝试valgrind。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM