c语言 - 输入年龄的第二个扫描不允许输入



嘿,我一直在努力解决这个问题。第二个scanf不允许输入整数。我检查过以确保一切都是正确的,但还是一样。我是不是错过了什么?输出在"0"处停止;在今年年底输入您的年龄:";

int main() {
int age;
char usrname;

printf("Hello, Welcome to the birth year calculator!");
printf("nnEnter Your Name: ");
scanf("%c", &usrname);
printf("Enter your age at the end of this year: ");
scanf("%d", &age);
return 0;
}

问题在于以下两行:

printf("nnEnter Your Name: ");
scanf("%c", &usrname);

您告诉用户输入由多个字符组成的内容,但您只是从输入流中提取一个字符并将其写入usrname

例如,如果输入Michael,则将从输入流中提取M,并在流中保留ichael

之后,您将执行行

scanf("%d", &age);

其将尝试将输入流上剩余的内容转换为整数。但是,这将失败,因为无法将ichael转换为整数。

通常不建议将scanf用于基于线路的用户输入。这是因为scanf不以直观的方式表现。例如,如上所述,它并不总是在一个函数调用中读取一行输入,这可能会造成麻烦,就像它对您所做的那样。

出于这个原因,通常建议使用函数fgets,如果可能的话,它将始终只读取一行输入。将一行输入读取为字符串后,可以尝试将其转换为整数,例如使用函数strtol

请注意,fgets还会将行末尾的换行符写入字符串,因此您可能需要删除它

从fgets((输入中删除尾部换行符

这里有一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char usrname[200];
char line[200];
int age;

printf("Hello, Welcome to the birth year calculator!");
printf("nnEnter Your Name: ");
fgets( usrname, sizeof usrname, stdin );
//remove newline character
usrname[strcspn(usrname,"n")] = '';
printf("Enter your age at the end of this year: ");
fgets( line, sizeof line, stdin );
age = strtol( line, NULL, 10 );
return 0;
}

除了char usrname的奇数选择外,它对我来说很有效。如果在输入前键入超过1个字母,它将导致第二个scanf()失败,您将看到错误检查。如果你不想让第一个提示的任何输入渗入第二个提示,那么你需要在两者之间刷新输入流。变量范围最小化:

#include <stdio.h>
int main() {
printf("nnEnter Your Name: ");
char usrname;
if(scanf("%c", &usrname) != 1) {
printf("usrname failedn");
return 1;
}
printf("Enter your age at the end of this year: ");
int age;
if(scanf("%d", &age) != 1) {
printf("age failedn");
return 1;
}
printf("name=%c, age=%dn", usrname, age);
return 0;
}

您可能希望使用字符串而不是用于名称的字符。如果你的用户名包含空格,那么你最好读一行fgets(),而不是scanf()。还将年龄更改为unsigned

#include <stdio.h>
#define TADMAN_IS_NOT_STINGY 254
#define str(s) str2(s)
#define str2(s) #s
int main() {
printf("nnEnter Your Name: ");
char usrname[TADMAN_IS_NOT_STINGY+1];
if(scanf("%" str(TADMAN_IS_NOT_STINGY) "s", usrname) != 1) {
printf("usrname failedn");
return 1;
}
printf("Enter your age at the end of this year: ");
unsigned age;
if(scanf("%u", &age) != 1) {
printf("usrname failedn");
return 1;
}
printf("name=%s, age=%un", usrname, age);
return 0;
}

第一个scanf仅从stdin中读取1个字符(因为usrname是字符而不是字符数组(,然后,如果stdin为空->则第二scanf会等待输入,否则第二次提示打印后会自动执行第二个scanf

在您的情况下,我假设在第一个提示时,您输入了超过1个字符,在这种情况下,第二个scanf将不会等待,而是使用第一个scanf没有读取的额外输入运行。例如,如果您在第一个提示中输入john,那么第一个scanfj,第二个scanfohn,并尝试转换为int

要解决此问题,请对usrname使用char数组,例如char usrname[128] = {0},或者在第一个提示(输入名称(时不要输入超过1个char。

int main() {
int age;
char usrname[128] = {0};

printf("Hello, Welcome to the birth year calculator!");
printf("nnEnter Your Name: ");
scanf("%s", usrname);
printf("Enter your age at the end of this year: ");
scanf("%d", &age);
return 0;
}

在设计这个C++答案之前,请阅读下面的注释。


这就是我所做的,它似乎运行得很好。

我创建了一个类,不确定这是否是必要的

class Person {
std::string userName;
int age;
}
main() {
Person shalofty;
std::cout << "Enter name and age" << std::endl;
std::cin >> shalofty.userName;
std::cin >> shalofty.age;
}

不同的人查看不同的优先级并提供不同的建议。这里,在注释代码中,是另一个接近原始版本但经过修饰的版本

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char usrname[200] = { 0 }; // ALWAYS initialise variables

printf("Hello, Welcome to the birth year calculator!");
printf("nnEnter Your Name: ");
if( scanf( "%[^n]", usrname ) != 1 ) { // test return codes
fprintf( stderr, "Scanf failedn" );
exit( EXIT_FAILURE );
}
// remove trailing 'n' from the name entered
usrname[ strcspn( usrname, "n" ) ] = '';
int usrage = 0; // define and initialise variables close to use
printf("Enter your age at the end of this year: ");
if( scanf( "%d", &usrage ) != 1 ) { // test return codes
fprintf( stderr, "Scanf failedn" );
exit( EXIT_FAILURE );
}
// do something with the user's input
printf( "Hello %s, who will be %d years old at year's endn", usrname, usrage );
return 0;
}

输出

Hello, Welcome to the birth year calculator!
Enter Your Name: Foo Bar
Enter your age at the end of this year: 42
Hello Foo Bar, who will be 42 years old at the end of this year

最新更新