C 计算一个句子的字母会产生随机输出

C 计算一个句子的字母会产生随机输出,c,arrays,string,scanf,fgets,C,Arrays,String,Scanf,Fgets,我需要我的程序输入用户想要输入的句子数,然后输入这些句子。然后,通过将其传递给函数letter(),我希望它计算每个字母在字符串中出现的次数。然而,我遇到以下问题: 当我输入行数时,程序只要求用户输入比输入的行数少1的行数(即,如果我想要两个句子,系统只提示我输入一个) 字母计数不能正常工作。这似乎是随机的 此外,我还想知道我是否正确地使用2D数组(即,我是否正确地填充它以及是否正确地通过函数传递它)。对于数组str[][],我希望第一个框表示句子数量,第二个框表示每行中的字符数量 这是我的密码

我需要我的程序输入用户想要输入的句子数,然后输入这些句子。然后,通过将其传递给函数
letter()
,我希望它计算每个字母在字符串中出现的次数。然而,我遇到以下问题:

  • 当我输入行数时,程序只要求用户输入比输入的行数少1的行数(即,如果我想要两个句子,系统只提示我输入一个)
  • 字母计数不能正常工作。这似乎是随机的
  • 此外,我还想知道我是否正确地使用2D数组(即,我是否正确地填充它以及是否正确地通过函数传递它)。对于数组
    str[][]
    ,我希望第一个框表示句子数量,第二个框表示每行中的字符数量

    这是我的密码:

    #include <stdio.h>
    
    void letter(int n, char str[][80]){
        char c = 'a';
        char alpha[26];
        int ltrcnt[26];
    
        for(int i = 0; i < 26; i++){
            ltrcnt[i] = 0;
        }
    
        for(int i = 0; i < 26; i++){
            for(int j = 0; j < 26; j++){
                for(int k = 0; k < 26; k++){
                    if(str[i][j] == c){
                        ltrcnt[k]++;
                    }
                    c++;
                }
            }
        }
    
        c = 'a';
        for(int i = 0; i < 26; i++){
            printf("%c: %d\n", c, ltrcnt[i]);
            c++;
        }
    }   
    
    int main(void){
        int n;
    
        printf("Enter number of lines: ");
        scanf("%d", &n);
    
        char str[n][80];
        printf("Enter a sentecne: ");
        for(int i = 0; i < n; i++){
            fgets(str[i], 80, stdin);
        }
    
        letter(n, str);
    }
    
    #包括
    无效字母(整数n,字符str[][80]){
    字符c='a';
    char-alpha[26];
    int ltrcnt[26];
    对于(int i=0;i<26;i++){
    ltrcnt[i]=0;
    }
    对于(int i=0;i<26;i++){
    对于(int j=0;j<26;j++){
    对于(int k=0;k<26;k++){
    if(str[i][j]==c){
    ltrcnt[k]++;
    }
    C++;
    }
    }
    }
    c=‘a’;
    对于(int i=0;i<26;i++){
    printf(“%c:%d\n”,c,ltrcnt[i]);
    C++;
    }
    }   
    内部主(空){
    int n;
    printf(“输入行数:”);
    scanf(“%d”和“&n”);
    char-str[n][80];
    printf(“输入一个句子:”);
    对于(int i=0;i
    第一个问题是,
    fgets()
    跳过一次迭代是因为在第一次输入后按ENTER键留下的
    换行符

    从换行符中清除输入缓冲区的一个简单例子是

     scanf("%d%*c", &n);  //eat the newline.
    
    对于第二个问题,在函数内部有三个嵌套循环,这没有意义。您没有在任何地方使用
    n
    的值。这没有任何意义,会导致垃圾输出

    比如说,

    • 您将索引
      j
      限制为
      25
      ,但实际上您接受它的长度为
      79
    • 您有循环变量
      k
      ,未正确使用
    一个合理的循环条件是


    • i
      直到
      n-1
      i第一个问题
      fgets()
      跳过一次迭代是因为在第一次输入后按ENTER键留下的
      换行符

      从换行符中清除输入缓冲区的一个简单例子是

       scanf("%d%*c", &n);  //eat the newline.
      
      对于第二个问题,在函数内部,有三个嵌套循环,没有意义。您没有在任何地方使用
      n
      的值。这没有意义,会导致垃圾输出

      比如说,

      • 您将索引
        j
        限制为
        25
        ,但实际上您接受它的长度为
        79
      • 您有循环变量
        k
        ,未正确使用
      一个合理的循环条件是

      • i
        n-1
        i
        当我输入行数时,程序只要求用户输入比输入的行数少1的行数

        我猜当你进行扫描时,它不会吞掉数字末尾的新行。因此,第一个
        fgets
        会得到数字所在行的剩余部分(空)

        字母计数不能正常工作。看起来好像是随机的

        在循环中,
        i
        应从
        0
        计数到
        n-1
        (即
        str
        )和
        j
        中的行数应从0计数到
        strlen(str[i])-1
        或更好,
        j
        应从
        0
        计数到
        str i][j]=='\0'
        因为strlen
        需要遍历所有字符本身,因此效率低下

        然后,您的内部循环应该查看
        str[i][j]
        是否介于
        a
        z
        a
        z
        之间,如果是,则从中减去
        'a'
        'a'
        ,并将其用作
        ltrcnt

        所谓“内部循环”,我指的是带有
        j
        的循环,就我所见,你不需要(k…
      循环的

      如果您坚持使用
      k
      循环,请记住在每次启动之前将
      c
      重置回
      'a'

      第二个问题的最小修复方法是:

      for(int i = 0; i < n; i++){
          for(int j = 0; str[i][j] != '\0'; j++){
              c = 'a'; // << was missing
              for(int k = 0; k < 26; k++){
                  if(str[i][j] == c){
                      ltrcnt[k]++;
                  }
                  c++;
              }
          }
      }
      
      for(int i=0;i
      我猜当你进行扫描时,它不会吞掉数字末尾的新行。因此,第一个
      fgets
      会得到数字所在行的剩余部分(空)

      字母计数不能正常工作。看起来好像是随机的

      在循环中,
      i
      应从
      0
      计数到
      n-1
      (即
      str
      )和
      j
      中的行数应从0计数到
      strlen(str[i])-1
      或更好,
      j
      应从
      0
      计数到
      str i][j]=='\0'
      因为strlen
      需要遍历所有字符本身,因此效率低下

      然后,您的内部循环应该查看
      str[i][j]
      是否介于
      a
      z
      a
      z
      之间,如果是,则从中减去
      'a'
      'a'
      ,并将其用作
      ltrcnt

      还有“inne”