字符双指针混淆行为

时间:2018-12-27 23:32:25

标签: c pointers

我正在https://www.codingame.com/做练习,练习一些C指针。

任务是将输入字符转换为ASCII艺术。 例如,字母A为:

 # 
# #
###
# #
# #

https://www.codingame.com/ide/puzzle/ascii-art

整个ASCII字母作为不同行(A到Z加?)的单个输入提供:

 #  ##   ## ##  ### ###  ## # # ###  ## # # #   # # ###  #  ##   #  ##   ## ### # # # # # # # # # # ### ### 
# # # # #   # # #   #   #   # #  #    # # # #   ### # # # # # # # # # # #    #  # # # # # # # # # #   #   # 
### ##  #   # # ##  ##  # # ###  #    # ##  #   ### # # # # ##  # # ##   #   #  # # # # ###  #   #   #   ## 
# # # # #   # # #   #   # # # #  #  # # # # #   # # # # # # #    ## # #   #  #  # # # # ### # #  #  #       
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  

我正在尝试将字母存储为双指针(alphabet_input)。

char ** alphabet_input;

int main()
{
    int length = 4;
    int height = 5;

    alphabet_input = (char **)malloc(sizeof(char *)*height);

    for (int i = 0; i < height; i++) {
        char ROW[1025];
        fgets(ROW, 1025, stdin);

        alphabet_input[i] = ROW;

        // print alphabet lines for the first time
        printf("%s", alphabet_input[i]);
    }

    // print alphabet lines for the second time
    printf("%s", alphabet_input[0]);
    printf("%s", alphabet_input[1]);
    printf("%s", alphabet_input[2]);
    printf("%s", alphabet_input[3]);
    printf("%s", alphabet_input[4]);

    return 0;
}

但是,当我尝试打印时,我会重复获得最后一行。这就是我得到的结果:

 #  ##   ## ##  ### ###  ## # # ###  ## # # #   # # ###  #  ##   #  ##   ## ### # # # # # # # # # # ### ### 
# # # # #   # # #   #   #   # #  #    # # # #   ### # # # # # # # # # # #    #  # # # # # # # # # #   #   # 
### ##  #   # # ##  ##  # # ###  #    # ##  #   ### # # # # ##  # # ##   #   #  # # # # ###  #   #   #   ## 
# # # # #   # # #   #   # # # #  #  # # # # #   # # # # # # #    ## # #   #  #  # # # # ### # #  #  #       
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  

我希望将输入打印两次:

 #  ##   ## ##  ### ###  ## # # ###  ## # # #   # # ###  #  ##   #  ##   ## ### # # # # # # # # # # ### ### 
# # # # #   # # #   #   #   # #  #    # # # #   ### # # # # # # # # # # #    #  # # # # # # # # # #   #   # 
### ##  #   # # ##  ##  # # ###  #    # ##  #   ### # # # # ##  # # ##   #   #  # # # # ###  #   #   #   ## 
# # # # #   # # #   #   # # # #  #  # # # # #   # # # # # # #    ## # #   #  #  # # # # ### # #  #  #       
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  
 #  ##   ## ##  ### ###  ## # # ###  ## # # #   # # ###  #  ##   #  ##   ## ### # # # # # # # # # # ### ### 
# # # # #   # # #   #   #   # #  #    # # # #   ### # # # # # # # # # # #    #  # # # # # # # # # #   #   # 
### ##  #   # # ##  ##  # # ###  #    # ##  #   ### # # # # ##  # # ##   #   #  # # # # ###  #   #   #   ## 
# # # # #   # # #   #   # # # #  #  # # # # #   # # # # # # #    ## # #   #  #  # # # # ### # #  #  #       
# # ##   ## ##  ### #    ## # # ###  #  # # ### # # # #  #  #     # # # ##   #  ###  #  # # # #  #  ###  #  

我应该如何操作Alphabet_input的索引以正确地将每一行打印为字符串?

我真的很困惑,因为在for循环中打印似乎效果很好。但是在此之后,索引似乎崩溃了。

1 个答案:

答案 0 :(得分:1)

for (int i = 0; i < H; i++) {
    char ROW[1025];
    fgets(ROW, 1025, stdin);
    alphabet_input[i] = ROW;
}

变量ROW在for主体的范围内,因此在每次迭代时都会创建并销毁它。您将alphabet_input[i]指向此变量,该变量会在迭代结束时立即销毁,因此最终会出现悬空指针。

您需要分配空间,然后将行的内容复制到其中,而不是将alphabet[i]指向局部变量。

char ** alphabet_input;
alphabet_input = malloc(height * sizeof *alphabet_input);

for (int i = 0; i < height; i++) {
    char row[1025];
    fgets(row, 1025, stdin);

    size_t len = strlen(row);

    alphabet_input[i] = malloc(len + 1);
    strcpy(alphabet_input[i], row);
}

您可能要根据所需的长度来调整上面的代码(例如1025而不是strlen,或删除尾随的新行等)

我想提出几点:

  • 这就是我推荐写malloc的方式:

    pointer_var = <no cast> malloc(<num_elements> * sizeof *pointer_var);
    alphabet_input = malloc(height * sizeof *alphabet_input);
    
  • sizeof(char)根据标准保证为1,因此您可以跳过sizeof(char)中的malloc

    alphabet_input[i] = malloc(len + 1);
    
  • 避免使用所有大写变量。它们通常用于C语言中的宏。