【问题标题】:Int array empty - CInt 数组为空 - C
【发布时间】:2016-04-13 14:17:31
【问题描述】:

我正在尝试编写一个程序,该程序将采用两组字符串 N 和 Q。该程序的目标是打印出 Q 中每个字符串在 N 中出现的次数。但是,我正在努力管理字符串和 C 中的指针,特别是我相信我的问题源于试图拥有一个字符串数组。执行以下代码时出现分段错误。我已经注释掉了我使用 printf() 进行调试的尝试。我相信当我尝试将 S 分配到 N_array 时会出现问题。

int main() {
    int N, Q; 
    char *N_array[1000], *Q_array[1000];

    scanf("%d", &N);

    for (int N_i = 0; N_i < N; N_i++) {
        //printf("made it through A for loop %d times\n", N_i+1);
        scanf("%s", N_array[N_i]);
    }

    scanf("%d", &Q);

    //Does the array contain any information?
    //for (int N_i = 0; N_i < N; N_i++) { printf("N_array[%d] == %d\n", N_i, N_array[N_i]);}

    for (int Q_i = 0; Q_i < Q; Q_i++) {
        //printf("Made it to B for loop\n");
        int occurs = 0, result;
        char s[21];
        scanf("%s", &s[21]);
        strcpy(Q_array[Q_i], s);
        for (int N_i2 = 0; N_i2 < N; N_i2++) {
            //printf("Made it to C for loop\n");
            result = strcmp(Q_array[Q_i], N_array[N_i2]);
            if (result == 0) occurs++;
        }
        printf("%d", occurs);
    }

    return 0;
} 

【问题讨论】:

  • 请记住,scanf 不会读取字符串中的空白字符。此外,如果您在 20 个字符的缓冲区上使用 scanf ,那么您应该使用 scanf("%19s", ... ) 这样您就不会溢出缓冲区。使用 fgets(而不是 gets)一次读取整行会更安全。

标签: c arrays string strcmp strcpy


【解决方案1】:

这里有个问题

for (int N_i = 0; N_i < N; N_i++) {
    //printf("made it through A for loop %d times\n", N_i+1);
    scanf("%s", N_array[N_i]);
}

N_Array 包含 1000 个指向 char 的指针,但这些指针中的每一个都指向,嗯.. 无处。它是一个未初始化的指针,指向您不拥有的随机内存位置。这是未定义的行为。你必须在scanf之前分配内存。

 N_Array[N_i] = malloc(max_length_of_string + 1);

另一个问题是这条线

 char s[21];
 scanf("%s", &s[21]);

scanf 的第二个参数应该只是s,而不是&amp;s[21],它就在你的数组之外。

下面一行的问题与我第一点中描述的相同

strcpy(Q_array[Q_i], s);

Q_array[Q_i] 尚未指向任何允许您写入的内存。你也应该在这里分配内存。

【讨论】:

  • 注意:“scanf 的第二个参数应该只是 s”暗示scanf("%s", s);。这和gets(s) 差不多。
【解决方案2】:
  1. scanf("%s", N_array[N_i]);

    这应该会导致SegFault 正如预期的那样,因为N_array[N_i] 不包含有效的内存地址。

    您需要使用malloccalloc 分配内存,将N_array[N_i] 指向一个有效的内存位置。

正确的代码是:

for (int N_i = 0; N_i < N; N_i++)
{
    if(!(N_array[N_i] = malloc((MAX_STRING_LENGTH + 1) * sizeof(char))))
    {
        printf("malloc failed!\n);
        exit(1);
    } 
    scanf("%s", N_array[N_i]);
}

  1. scanf("%s", &amp;s[21]);

    这是不正确的,因为 %s 期望 char *&amp;s[21] 的类型是 char **

    您需要改用scanf("%20s", s);

    这种方式scanf 最多只能读取20 字符(因为我们有char s[21]。所以将最后一个字节留给\0 字符),因此这将避免意外的缓冲区溢出(其中输入的字符串长度由用户大于 20)。


  1. strcpy(Q_array[Q_i], s);

    这里Q_array[Q_i] 再次指向无效的内存地址,因为它包含垃圾值。使用malloccalloc等先分配内存。

正确的代码可能是:

if(!(Q_array[Q_i] = malloc((MAX_STRING_LENGTH + 1) * sizeof(char))))
{
    printf("malloc failed!\n);
    exit(1);
}
strcpy(Q_array[Q_i], s);  

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 2018-08-09
    • 1970-01-01
    • 2014-05-18
    • 2014-03-02
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多