【问题标题】:Uable to declare a char string properly in C无法在 C 中正确声明 char 字符串
【发布时间】:2021-05-12 17:44:48
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int i, j,
      matriz[4][4] = {0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, l, c,
      matrizcontrolo[4][4] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      ponto = 0, ntentativa = 0;
  const char array1[4][4] = {"0000", "0000", "0000", "0000"};
  for (i = 0; i < 4; i++) {
    do {
      printf("Tentativa %d\n", ntentativa + 1);
      do {
        printf("Linha:\n");

        scanf("%d", &l);
      } while (l < 1 || l > 4);
      do {
        printf("Coluna:\n");
        scanf("%d", &c);
      } while (c < 1 || c > 4);
    } while (matrizcontrolo[l][c] == 1);
    if (matriz[l - 1][c - 1] == 0) {
      printf("Splash!\n");
      strcpy(array1[l - 1][c - 1], "x");
    } else {
      printf("Boom!\n");
      ponto = ponto + 2;
      i--;
      strcpy(array1[l - 1][c - 1], "S");
    }
    matrizcontrolo[l][c] = 1;
    ntentativa++;
  }
  printf("O campo de batalha foi\n");
  for (i = 0; i < 4; i++) {
    printf("\n");
    printf("%s ", *array1[i]);
  }
  if (ponto == 8) {
    printf("Parabéns, acertou em todos os barcos e a sua pontuação foi de %d",
           ponto);
  }
  return 0;
}

我收到一条错误消息:

main.c:31:20: 警告:传递“strcpy”的参数 1 使指针从整数而不进行强制转换 [-Wint-conversion]
/usr/include/string.h:129:14:注意:预期为“char * restrict”,但参数的类型为“char”
main.c:37:20:警告:传递“strcpy”的参数 1 使指针从整数而不进行强制转换 [-Wint-conversion]
/usr/include/string.h:129:14:注意:预期为“char * restrict”,但参数的类型为“char”
main.c:45:18:警告:格式“%s”需要“char *”类型的参数,但参数 2 的类型为“int”[-Wformat=]

然后就简单了:

分段错误(核心转储)

当我尝试通过在 matriz 变量中插入值来运行程序时。

谁能帮帮我?

提前致谢!

【问题讨论】:

    标签: arrays c string


    【解决方案1】:

    坏消息是你用错了strcpy。好消息是您无论如何都不需要使用它。

    仅供参考,strcpy 需要一个足以存储您正在复制的源字符串的非常量目标缓冲区,并包括一个用于终止 nullchar 的额外位置。您的目标是单个 char,而不是 char*

    此外,您的字符串缓冲区全部都过小。字符串 "0000" 需要 五个 个字符来存储:四个字符串,加上一个用于终止 nullchar。

    最后,字符串缓冲区数组不能是const。您将更改这些行中的数据。

    此代码不应使用strcpy任何地方。您真正要做的就是将终止字符串中的特定字符设置为特定值。 C 提供了一种方法:assignment。您的程序的修改版本如下。我无法证明游戏玩法是否正确,但它解决了您在报告的错误方面遇到的具体问题,并向您展示了您真正追求的直接单元分配。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int i, j, l, c, ponto = 0, ntentativa = 0;
    
        int matriz[][4] = {
            {0, 0, 1, 1}, 
            {0, 0, 0, 0}, 
            {1, 1, 0, 0}, 
            {0, 0, 0, 0}
        };
    
        int matrizcontrolo[][4] = {
            {0, 0, 0, 0}, 
            {0, 0, 0, 0}, 
            {0, 0, 0, 0}, 
            {0, 0, 0, 0}
        };
            
        char array1[][5] = {
            "0000", 
            "0000", 
            "0000", 
            "0000"
        };
    
        for (i = 0; i < 4; i++)
        {
            do
            {
                printf("Tentativa %d\n", ntentativa + 1);
                do
                {
                    printf("Linha:\n");
                    scanf("%d", &l);
                } while (l < 1 || l > 4);
                do
                {
                    printf("Coluna:\n");
                    scanf("%d", &c);
                } while (c < 1 || c > 4);
            } while (matrizcontrolo[l][c] == 1);
    
            if (matriz[l - 1][c - 1] == 0)
            {
                printf("Splash!\n");
                array1[l-1][c-1] = 'x';
            }
            else
            {
                printf("Boom!\n");
                ponto = ponto + 2;
                i--;
                array1[l - 1][c - 1]= 'S';
            }
            matrizcontrolo[l][c] = 1;
            ntentativa++;
        }
    
        printf("O campo de batalha foi\n");
        for (i = 0; i < 4; i++)
        {
            puts(array1[i]);
        }
    
        if (ponto == 8)
        {
            printf("Parabéns, acertou em todos os barcos e a sua pontuação foi de %d",
                   ponto);
        }
        return 0;
    }
    

    【讨论】:

    • 唉,您的代码在最后一个循环中打印 array1 后也会产生分段错误...
    • 我已经隔离了分段错误的原因:就是这行代码 `` matrizcontrolo[l][c] = 1; ```如果评论这一行,错误就会消失......知道是什么原因造成的吗?
    • 是的,这是原始代码中的一个错误。那应该是 matrizcontrolo[l-1][c-1] = 1; Fyi ,同样的错误在第一个 do-loop 中,应该是 } while (matrizcontrolo[l-1][c-1] == 1); 看看当你反对从零开始的索引时会发生什么?
    【解决方案2】:

    老实说,我不确定您的程序背后的逻辑和目标到底是什么。但是问题很清楚,都是可以解决的:

    1. 在这种语法中:

      strcpy(array1[l - 1][c - 1], "x");
      

      当你用两个下标操作符访问二维数组时,它不再被称为指针,而是char类型。而strcpy() 会询问您以下参数:

      char *strcpy(char *dest, const char *src);
      

      您需要传递array1[] (char*),而不是array1[][] (char)。简单来说,你不需要strcpy()函数:

      array[l - 1][c - 1] = 'x';
      
    2. 在定义的二维数组中没有足够的房间。每个字符串的末尾总是有一个以空字符结尾的字符。因此,不要为 0000 提供 4,而是将其增加 1,即 5,并且与其他类型为 char[]char[][] 的类似。

    3. 在下面的语句中:

      matriz[4][4] = {0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}
      

      您以不正确的方式初始化二维数组。您需要使用嵌套大括号:

      matriz[4][4] = {{0, 0, 1, 1}, {0, 0, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}}
      

      matrizcontrolo[][]做同样的事情。

    4. 您无需添加星号来取消引用:

      printf("%s ", *array1[i]);
                    ^^^___ remove the asterisk
      

    【讨论】:

    • Re 1.: 将array1[] 传递给strcpy 在语法上是正确的,但不会按照预期进行。只需将'X' 分配给array1[][] 就可以了。
    • @Gerhardh 是的,我现在已经澄清了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多