fgets 不接受最后一个值?
fgets not accepting last value?
我有一道作业题:-
1) User will input the number of names he wants to input.
2) He will then input those names.
3) We have to print those names.
这是我针对上述问题写的代码:-
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
int main()
{
int n; // number of names user wants to input.
scanf("%d", &n);
char *array[n]; //creating an array of pointers.
int i;
for(i = 0; i < n; i++)
{
array[i] = malloc(21*sizeof(char)); // allocating memory to each pointer.
}
for(i = 0; i < n; i++)
{
fgets(array[i], 21, stdin); //getting the values.
}
for(i = 0; i < n; i++)
{
printf("%s", array[i]); // printing those values.
}
return 0;
}
以上代码的问题是它没有打印用户输入的最后一个值。
示例:
示例输入:-
5
raj
chris
ben
abhay
gautam
预期输出:-
raj
chris
ben
abhay
gautam
我的输出:-
raj
chris
ben
abhay
编辑:
更改此行后:-
scanf("%d", &n);
到
scanf("%d ", &n);
它工作正常。
第一个 scanf("%d", &n);
在输入流中留下了一个换行符,因此 fgets
读取的第一个字符串只是一个换行符。在阅读名称之前,您需要删除该换行符。
如果你改变
for(i = 0; i < n; i++)
{
printf("%s", array[i]); // printing those values.
}
至
for(i = 0; i < n; i++)
{
printf("String %d : |%s|", i, array[i]); // printing those values.
}
很容易看出...
您将得到输出:
String 0 : |
|String 1 : |raj
|String 2 : |chris
|String 3 : |ben
|String 4 : |abhay
|
注意第一个字符串只是一个换行符...
我通常的建议是...不要使用 scanf
(用于读取数字)。它看起来是一个非常简单的功能,但实际上很难使用并且会导致很多错误。而是使用 fgets
后接 sscanf
。您还应该检查 sscanf
/scanf
实际上 returns 1.
在输入缓冲区中存储了调用后的换行符'\n'
scanf("%d", &n);
在使用 fgets
之前,您必须从输入缓冲区中删除该字符。
你可以使用这个电话
scanf( "%*[ \t\n]" );
还要考虑到 fgets 反过来可以附加一个带有换行符的字符串,通常应该从字符串中删除换行符,如下面的演示程序所示。
这是演示程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { STRING_SIZE = 21 };
size_t n;
scanf( "%zu", &n );
scanf( "%*[ \t\n]" );
char **s = malloc( n * sizeof( char * ) );
for ( size_t i = 0; i < n; i++ ) s[i] = malloc( STRING_SIZE );
for ( size_t i = 0; i < n; i++ )
{
fgets( s[i], STRING_SIZE, stdin );
s[i][strcspn( s[i], "\n" )] = '[=12=]';
}
for ( size_t i = 0; i < n; i++ ) puts( s[i] );
for ( size_t i = 0; i < n; i++ ) free( s[i] );
free( s );
return 0;
}
它的输出符合预期
raj
chris
ben
abhay
gautam
我有一道作业题:-
1) User will input the number of names he wants to input.
2) He will then input those names.
3) We have to print those names.
这是我针对上述问题写的代码:-
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
int main()
{
int n; // number of names user wants to input.
scanf("%d", &n);
char *array[n]; //creating an array of pointers.
int i;
for(i = 0; i < n; i++)
{
array[i] = malloc(21*sizeof(char)); // allocating memory to each pointer.
}
for(i = 0; i < n; i++)
{
fgets(array[i], 21, stdin); //getting the values.
}
for(i = 0; i < n; i++)
{
printf("%s", array[i]); // printing those values.
}
return 0;
}
以上代码的问题是它没有打印用户输入的最后一个值。
示例: 示例输入:-
5
raj
chris
ben
abhay
gautam
预期输出:-
raj
chris
ben
abhay
gautam
我的输出:-
raj
chris
ben
abhay
编辑:
更改此行后:-
scanf("%d", &n);
到
scanf("%d ", &n);
它工作正常。
第一个 scanf("%d", &n);
在输入流中留下了一个换行符,因此 fgets
读取的第一个字符串只是一个换行符。在阅读名称之前,您需要删除该换行符。
如果你改变
for(i = 0; i < n; i++)
{
printf("%s", array[i]); // printing those values.
}
至
for(i = 0; i < n; i++)
{
printf("String %d : |%s|", i, array[i]); // printing those values.
}
很容易看出...
您将得到输出:
String 0 : |
|String 1 : |raj
|String 2 : |chris
|String 3 : |ben
|String 4 : |abhay
|
注意第一个字符串只是一个换行符...
我通常的建议是...不要使用 scanf
(用于读取数字)。它看起来是一个非常简单的功能,但实际上很难使用并且会导致很多错误。而是使用 fgets
后接 sscanf
。您还应该检查 sscanf
/scanf
实际上 returns 1.
在输入缓冲区中存储了调用后的换行符'\n'
scanf("%d", &n);
在使用 fgets
之前,您必须从输入缓冲区中删除该字符。
你可以使用这个电话
scanf( "%*[ \t\n]" );
还要考虑到 fgets 反过来可以附加一个带有换行符的字符串,通常应该从字符串中删除换行符,如下面的演示程序所示。
这是演示程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { STRING_SIZE = 21 };
size_t n;
scanf( "%zu", &n );
scanf( "%*[ \t\n]" );
char **s = malloc( n * sizeof( char * ) );
for ( size_t i = 0; i < n; i++ ) s[i] = malloc( STRING_SIZE );
for ( size_t i = 0; i < n; i++ )
{
fgets( s[i], STRING_SIZE, stdin );
s[i][strcspn( s[i], "\n" )] = '[=12=]';
}
for ( size_t i = 0; i < n; i++ ) puts( s[i] );
for ( size_t i = 0; i < n; i++ ) free( s[i] );
free( s );
return 0;
}
它的输出符合预期
raj
chris
ben
abhay
gautam