我试图制作一个小帐户注册程序。它会提示用户userID
和password
。我正在userID
部分工作,但它看起来并不正确。如果我输入< 8
字符userID
,它会正常工作,但当我输入userID
字符超过16
时,会向用户询问不同的userID
{1}}打印两次。为什么?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
// Setting up variables
char userID[18];
char passcode[51];
// Firstly promt the user for user ID
do // This loop is for asking the user to type another userID if his chosen one isn't approprite
{
printf("Please choose your user ID! (it must be between 6 - 16 charaters long)\n");
for (int i = 0; i < 17; i++) // This loop store the userID into the character array
{
userID[i] = getchar(); // Store userID into array character by character
if (userID[i] == '\n')
{
userID[i+1] = '\0';
break;
}
}
}
while (strlen(userID) < 7 || (strlen(userID) > 16 && userID[16] != '\n'));
// Printing info on the screen.
printf("Your acount info are:\n\tuserID : %s\tpasscode: ", userID);
答案 0 :(得分:2)
如果我输入
< 5
个字符userID
,它会正常工作,但当我输入userID
个字符超过16
时,会询问用户的消息不同的userID
打印两次。为什么?
当您输入的16
个字符数超过17
时,如果您未输入userID
,则'\n'
个字符会被扫描到字符串userID
中,不会出现空字符放在字符串strlen(userID)
的末尾。
然后,当您使用\0
时,会调用未定义的行为,因为最后没有放置终止index + 1
个字符。试着这样做:
当你重新开始迭代时,剩余的额外整数将被接收。
解决方案:
为避免上述问题:
flush
位置放置一个空字符。 stdin
每次迭代结束时的do
{
printf("Please choose your user ID! (it must be between 6 - 16 charaters long)\n");
for (int i = 0; i < 17; i++)
{
userID[i] = getchar();
userID[i+1] = '\0'; //placing null character at the position index+1
if(userID[i] == '\n')
{
userID[i] = '\0';
break;
}
}
fflush(stdin); //flushing the extra input at the end of each iteration
} while (strlen(userID) < 7 || (strlen(userID) > 16 && userID[16] != '\n'));
。
more than 16 123456789
1123
123456789
示例输入:
Please choose your user ID! (it must be between 6 - 16 charaters long)
more than 16 123456789
Please choose your user ID! (it must be between 6 - 16 charaters long)
1123
Please choose your user ID! (it must be between 6 - 16 charaters long)
123456789
Your acount info are:
userID : 123456789
passcode:
示例输出:
fflussh(stdin)
注意:
避免使用fflush(stdin)
因为@JonathanLeffler中的 comments 所示的可移植性问题。另外,这里有一个解释性的帖子,为什么不使用fflush(stdin)
:click
以下是您的代码实现,避免使用do
{
int i;
printf("Please choose your user ID! (it must be between 6 - 16 charaters long)\n");
for (i = 0; (userID[i] = getchar()); i++)
{
userID[i+1] = '\0'; //placing null character at the position index+1
if(userID[i] == '\n')
{
userID[i] = '\0';
break;
}
//if user enters more than 16 characters then,
//scan in 17th character for `strlen(userID)` purpose and
//consume all other characters using an integer `c`
if( i > 17)
{
int c;
while( ((c = getchar())!= '\n') && (c!=EOF) );
break;
}
}
} while ( (strlen(userID) < 7) || (strlen(userID) > 16 ) );
@implementation IntroductViewCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)resizeWithWidth:(NSInteger)width {
self.contentView.bounds = CGRectMake(0, 0, width, width / 3);
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
}
@end