指向字符串字符的指针数组

array of pointers to string characters

当输入给定 5 个时,而不是要求 5 个字符串只需要 4 个,为什么会这样? 为什么默认保存 *a+0 = '\n' 我也试过第 9 行 scanf("%d %c", &n &ch ),但问题是一样的。

    #include <stdio.h>
    #include <string.h>

int main()
    {
        int n;
        char ch;
        printf("no of elements\n");
        scanf("%d ", &n ); //line 9
        //asking for number of pointer in array 
        char *a[n];
        puts("string");
        for (int i = 0; i < n; ++i){
            gets(a+i);
        }
        puts("-----");
        for (int j = 0; j < n; ++j){
            puts(a+j);
        }
        puts("-----");
        puts(a);
        puts("-----");
        puts(a+2);

        return 0;
    }

你可能想要这个:

#include <stdio.h>
#include <string.h>

int main()
{
  int n;
  printf("no of elements\n");
  scanf("%d", &n);  // No space after the %d !

  char dummy[2];            // these 2 lines are needed for absorbing the leftover
  fgets(dummy, 2, stdin);  // \n from scanf (mixing fgets and scanf is a bad idea)

  char *a[n];       // here we'll have an array of n pointers to char. For the moment
                    // the array is not initialized and the pointers point nowhere

  puts("string");

  for (int i = 0; i < n; ++i) {
    a[i] = malloc(100);         // allocate memory for a string of a maximum length of 99.
                                // + one char for the NUL terminator
                                // Allocating a fixed size is awkward, but it will
                                // do here for demonstration purposes

    fgets(a[i], 100, stdin);    // limit the length of string to 100 in order
                                // to avoid buffer overflow
                                // it's basically the same as gets(buffer)
  }

  puts("-----");
  for (int j = 0; j < n; ++j) {
    puts(a[j]);
  }

  puts("-----");
  puts(a[0]);
  puts("-----");
  puts(a[2]);

  return 0;
}

输入输出:

no of elements
3
string
11
22
33
-----
11

22

33

-----
11

-----
33

为简洁起见,避免了错误检查。

对于根据 C 标准的初学者,不带参数的函数 main 应声明为

int main( void )

本声明中声明的变量

char ch;

程序中未使用,应删除。

而且您的程序中没有使用 header <string.h> 中的任何声明。所以 header 可以被删除。

您声明了一个指向类型 char

的可变长度指针数组
char *a[n];

然而,数组的元素没有被初始化并且具有不确定的值。由于 for 循环中的这条语句,程序具有未定义的行为

gets(a+i);

您必须为要输入的每个字符串分配内存。

还要考虑到函数 gets 是不安全的,C 标准不再支持它。而是使用函数 fgets。此外,函数调用中的参数必须是 *( a + i ) 而不是 a + i 因为最后一个表达式的类型是 char ** 而不是所需的类型 char *.

所以一个有效的代码可以通过以下方式查找示例

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    size_t n;
    const size_t SIZE = 20;

    printf( "no of elements: " );

    if ( scanf( "%zu%*c", &n ) != 1 || n == 0 ) n = 1;

    char * a[n];

    for ( size_t i = 0; i < n; i++ )
    {
        *( a + i ) = malloc( SIZE );    
    }

    puts("string");

    for ( size_t i = 0; i < n; ++i )
    {
        fgets( *( a + i ), SIZE, stdin );
    }

    puts("-----");

    for ( size_t i = 0; i < n; ++i )
    {
        printf( "%s", *( a + i ) );
    }

    puts( "-----" );
    printf( "%s", *a );

    puts( "-----" );
    printf( "%s", *( a + 2 ) );

    for ( size_t i = 0; i < n; i++ )
    {
        free( *( a + i ) );
    }

    return 0;
}

它的输出可能看起来像

no of elements: 5
string
A
B
C
D
E
-----

A
B
C
D
E
-----
A
-----
C

注意这个声明

    if ( scanf( "%zu%*c", &n ) != 1 || n == 0 ) n = 1;

使用格式说明符 &zu 读取变量 n 后,您需要从输入缓冲区中删除与按下的 Enter 键对应的换行符。否则 fgets 的下一次调用将读取一个空字符串。