【问题标题】:Reading array of string in C在C中读取字符串数组
【发布时间】:2017-02-16 20:34:27
【问题描述】:

我需要从每个字符串中的 2 个字母读取 n 个字符串的数组(例如 n = 3,需要读取“ab bf cs”附近的内容)。我使用这段代码并得到分段错误:

int n;
scanf("%d", &n);
char array[n][2];
char *tmp;
for (int i = 0; i < n; i++)
{
    scanf("%s", &tmp);
    strcpy(array[i], tmp);
}

请帮我解决它!

【问题讨论】:

    标签: c input segmentation-fault scanf stdin


    【解决方案1】:

    问题 1

    要存储长度为 2 的字符串,您需要一个大小为 3 的 char 数组。使用:

    char array[n][3];
    

    问题 2

    您在调用scanf 时使用了&amp;tmp。这在两个帐户上都是错误的。

    1. 类型不合适。 &amp;tmp 的类型是 char**scanf 需要带有 %s 格式说明符的 char*

    2. &amp;tmp 不能保存字符串。

    你可以使用

    scanf("%s", tmp);
    

    从类型的角度来看是可以的,但从运行时的角度来看就不行,因为tmp 没有指向任何有效的东西。

    您可以完全取消 tmp 并使用:

    scanf("%s", array[i]);
    

    整个代码块可以是:

    int n;
    scanf("%d", &n);
    char array[n][3];
    for (int i = 0; i < n; i++)
    {
        // Make sure you don't read more than 2 chars.
        scanf("%2s", array[i]);
    }
    

    【讨论】:

      【解决方案2】:

      您需要在此处解决一些问题。

      1. 请记住,一个“字符串”(char[]) 总是以空终止字符 \0 结尾。因此,无论何时创建char[],都必须为此留出足够的空间。例如:

        char str[3] = "foo"; 看起来像 ['f', 'o', 'o'],但是

        char str[4] = "foo"; 看起来像 ['f', 'o', 'o', '\0']

        使用前者可能会出现意想不到的后果。

        这意味着您应该将char array[n][2] 更改为char array[n][3]

      2. 记住pointers are different than arrays。如果要使用指针,则必须为其分配内存,否则很可能会出现段错误。

        在您的程序中,它很简单,您可能不使用指针就可以逃脱,尤其是因为您知道要存储的每个字符串的长度 (2)。

        您可以将char *tmp 更改为char tmp[3]

      3. 您实际上可以重构您的代码,因此您根本不需要tmp 变量。如果你愿意,你可以直接将你读到的单词存储到数组中。例如:

        scanf("%s", array[n]);
        
      4. 如果您真的坚持将tmp 变量用作char *,则为其分配内存,如下所示:

        char *tmp = (char*)malloc(3 * sizeof(char));
        
      5. 作为旁注,如果您遵守 ISO C90 标准,则不应在代码中混合变量声明,因此在您有 for(int i = 0...) 的循环中,您应该在顶部声明 int i;文件,然后在循环中分配它for(i = 0...)

      【讨论】:

      • char *tmp = (char*)malloc(3 * sizeof(char)); 可以简化为 char *tmp = malloc(3);char *tmp = malloc(sizeof *tmp * 3);
      【解决方案3】:

      首先,正如用户 3121023 在 cmets 中指出的那样,char *tmp; 创建了一个没有分配内存的指针。 scanf() 需要一个数组,并且您需要用于终止 '\0' 的空间(这可能是您的分段错误的根源)。所以你可以试试scanf("%s", array[i]);

      其次,最好使用"%2s" 而不是"%s",这样用户就不会输入 3 位数字并溢出缓冲区。

      这是一个解决方案。

      int n;
      scanf("%d", &n);
      char array[n][3];
      for (int i = 0; i < n; i++)
      {
          scanf("%2s", array[i]);
      }
      

      【讨论】:

      • 不同意“您不能将数组声明为常量或整数文字以外的任何大小。” C99 和可选的 C11 允许可变长度数组。
      • 谢谢。我没有意识到这一点。我已经更新了我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-29
      • 2014-11-21
      • 2011-11-01
      • 2013-03-20
      • 2012-10-19
      • 2018-05-02
      • 2023-04-04
      相关资源
      最近更新 更多