如果用户输入超过16个字符,为什么我的C程序会打印两次消息?

时间:2016-07-09 03:53:55

标签: c loops

我试图制作一个小帐户注册程序。它会提示用户userIDpassword。我正在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);

1 个答案:

答案 0 :(得分:2)

  

如果我输入< 5个字符userID,它会正常工作,但当我输入userID个字符超过16时,会询问用户的消息不同的userID打印两次。为什么?

  • 当您输入的16个字符数超过17时,如果您未输入userID,则'\n'个字符会被扫描到字符串userID中,不会出现空字符放在字符串strlen(userID)的末尾。

  • 然后,当您使用\0时,会调用未定义的行为,因为最后没有放置终止index + 1个字符。试着这样做:

  • 当你重新开始迭代时,剩余的额外整数将被接收。

解决方案:

为避免上述问题:

  1. 在每次迭代时在flush位置放置一个空字符。
  2. 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
    
  3. 示例输入:

    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