格式化字符串输入和C中的错误

时间:2017-08-10 16:31:51

标签: c

struct account {
  float interestRate;
  char accountType[21];
};

void writeAccounts() {
  struct account Acc;
  FILE *fp = fopen("test.txt", "a");

  printf("New interestRate : ");
  scanf("%f", &Acc.interestRate);
  printf("New  accountType : ");
  scanf("%*c%20[^\n]", Acc.accountType);

  fprintf(fp, "%.2f %s\n", Acc.interestRate, Acc.accountType);

  fclose(fp);
}

int main() {
  int select = 0;

  do {
    scanf("%d", &select);
    switch (select) {
      case 1:
        displayAccounts();
        break;
      case 2:
        getRecNo();
        break;
      case 3:
        writeAccounts();
        break;
    }
  } while (select != 0);

  return 0

上面是我的代码(删除了一些不相关的函数)。 当我尝试在" writeAccounts"中为accountType键入超过20个字符的字符串时函数,程序开始跳过几步,直到它保存我输入的所有字符。 (不能使用FGETS !!我的教授不允许:/)

http://imgur.com/a/eKQRu

  1. 为什么会这样?
  2. 不是20%[^ \ n]意味着即使用户投入更多也只能接受20个字符?
  3. 可能的方法来防止这种情况发生?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 为什么会这样?
  2.   

多余的输入保留在输入缓冲区中,并由后续scanf次调用读取。

  
      
  1. 不是20%[^ \ n]意味着即使用户投入更多也只能接受20个字符?
  2.   

这是正确的,如上所述,任何剩余的输入都不会被处理。

  
      
  1. 可能的方法来防止这种情况发生?
  2.   

扫描成功后(20个字符或更少),换行符仍保留在输入缓冲区中。你可以做各种各样的事情。

首先,您可以检查下一个输入字符 是否为预期的换行符:

if (getchar() != '\n') {
    // add code here to report the error and take evasive action
}

或者您可以通过清除缓冲区来截断并忽略任何多余的输入:

int c;
while ((c = getchar()) != '\n' && c != EOF) {
    // eats up the input buffer, the code is in the loop control
}