指向字符串字符的指针数组
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
的下一次调用将读取一个空字符串。
当输入给定 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
的下一次调用将读取一个空字符串。