C 当我在程序中选择某个选项时,我不断得到一个无限循环

C 当我在程序中选择某个选项时,我不断得到一个无限循环,c,C,我有一个程序,它要求用户输入信息,并将其存储在文件中,允许你编辑条目或添加新条目,或通过将工资总额设置为0来删除条目 然而,当我试图修改一个名字时,它不会修改,当我试图修改性别时,它会导致一个无限循环。any1能告诉我出了什么问题吗 我认为我在循环中所做的中断声明有问题,提前谢谢 #include <stdio.h> #include <stdlib.h> typedef struct { int employee_number; char employee_na

我有一个程序,它要求用户输入信息,并将其存储在文件中,允许你编辑条目或添加新条目,或通过将工资总额设置为0来删除条目

然而,当我试图修改一个名字时,它不会修改,当我试图修改性别时,它会导致一个无限循环。any1能告诉我出了什么问题吗

我认为我在循环中所做的中断声明有问题,提前谢谢

#include <stdio.h>
#include <stdlib.h>
typedef struct
{
  int employee_number;
  char employee_name[20];
  char employee_sex;
  int employee_gross_salary;

}information;
int main()
{//open main function
  information customer;
  int i;
  int choice;
  int number;
  int choice2;
  int number2;
  FILE *fptr = fopen("emp.dat", "wb+");

  //asking user to enter atleast 5 customers into datarecords
  for(i = 0; i<1;i++)
  {//open for
    printf("enter employee's number\n");
    scanf("%d",&customer.employee_number);
    getchar();
    printf("enter the employee's name\n");
    scanf("%s", customer.employee_name);
    getchar();
    printf("enter employee's gender\n");
    scanf("%d",&customer.employee_sex);
    getchar();
    printf("enter employee's salary\n");
    scanf("%d",&customer.employee_gross_salary);
    getchar();
    fwrite(&customer,sizeof(customer),1,fptr);
  }//close for 

  for(;;)
  {//open for
    printf("\n what would you like to do\n1]Add entry\n 2]Delete entry \n3]Modify     entry\n4]view entries\n5]exit\n");
    scanf("%d", &choice);
    if(choice == 5)
    {break;}
    else if(choice == 1)
    {//open else if
      fseek(fptr,0, SEEK_END);// check the parameters here
      printf("enter new employee's number\n");
      scanf("%d",&customer.employee_number);
      getchar();
      printf("enter the new employee's name\n");
      scanf("%s", customer.employee_name);
      getchar();
      printf("enter new employee's gender\n");
      scanf("%d",&customer.employee_sex);
      getchar();
      printf("enter new employee's salary\n");
      scanf("%d",&customer.employee_gross_salary);
      getchar();
      fwrite(&customer,sizeof(customer),1,fptr);
      continue;

    }//close else if
    else if( choice == 2)
    {//open else if
      printf("enter the employee number of person\n");
      scanf("%d",&number);
      fseek(fptr,0,SEEK_SET);
      while((fread(&customer,sizeof(customer), 1,fptr))!=NULL)
      {//open while

        if(customer.employee_number == number)
        {//open if
          customer.employee_gross_salary = 0;
        }//close if

      }//close while
      continue;
    }//clsoe else if
    else if(choice == 3)
    {//open else if
      printf("enter the employee number of the employee you would like to modify\n");
      scanf("%d",&number2);
      printf("what would you like to modify\n");
      scanf("%d", &choice2);
      fseek(fptr,0,SEEK_SET);
      while((fread(&customer, sizeof(customer),1,fptr))!= NULL)
      {//open while within else if
        //1 to midify name, 2 to modify gender 3 for salary
        if(customer.employee_number == number2)
        {//open if

          if(choice2 == 1)
          {

            printf("enter new name\n");
            scanf("%s",customer.employee_name );
            break;
          }
          else if(choice2 == 2)
          {
            printf("enter new gender");
            scanf("%d", &customer.employee_sex);
            break;  
          }
          else if(choice2 == 3)
          {
            printf("enter new gross salary\n");
            scanf("%d",    &customer.employee_gross_salary);
            break;
          }

        }//close if

      }//close while within else if
      continue;
    }//close else if
    else if(choice == 4)
    {
      fseek(fptr,0,SEEK_SET);
      while((fread(&customer,sizeof(customer),1,fptr))!= NULL)
        printf("\n%d\t%s\t%c\t%d\n",            customer.employee_number,customer.employee_name,customer.employee_sex,customer.employee_gro    ss_salary);
      continue;
    }
  }//close for
  return 0; 
}//close main function
#包括
#包括
类型定义结构
{
国际雇员联合会编号;
char employee_name[20];
性别;
int员工工资总额;
}信息;
int main()
{//打开主函数
客户信息;
int i;
智力选择;
整数;
综合选择2;
整数2;
文件*fptr=fopen(“emp.dat”、“wb+”);
//要求用户在数据记录中输入至少5个客户

对于(i=0;i这不是调试的答案,只是一些重构代码和未来写作的建议:

一,。 避免使用“中断”和“继续”,它们是流量断路器、bug源、坏消息和坏消息,对于go-to也是一样的,它们在这里用于特定的无其他方式的情况

您可以执行以下操作:

int end = 0,
    choice = 0;

do
{
    fprintf(stdout, "1:Do stuff\n2:Do other stuff\n3: Do another stuff\nX: end\n");
    while(fscanf(stdin, "%d", &choice) != 1){}
    if(choice == 1)
    {
        //Do stuff
    }
    else if (choice == 2)
    {
        //Do other stuff
    }
    else if (choice == 3)
    {
        //Do another stuff
    }
    else
    {
        end = 1;
    }
}while(end == 0);
return 0;
无需继续,无需中断,更易于修改,更易于编写,更易于阅读,更简短,用两个字来说:更好的方式

二,。 用英语写作,通常,你有一个完整的键盘,不需要用字母支付,输入整个单词的速度几乎一样快,并且有助于其他人理解。 此外,它还可以帮助您在编写文本或代码时减少错误

三,。 如果多个变量属于同一类型,则可以一次声明多个变量:

int var1;
int var2;
int var3;
...
是冗长且重复的,你可以写:

int var1,
    var2,
    var3;
一个好习惯是总是初始化变量,这有助于防止一些错误:

int var1=0,
    var2=0,
    var3=0;
四,。 每当你使用一个函数,测试它的返回,就会有很多错误发生,因为你认为“这是一个标准函数,它是防错误的”。例如,你的emp.dat的fopen。它可能会失败(事实上,在某一点上会失败)

五,。 如果你是一个乞丐(这并不丢脸,每个人都是从某个角度开始的,我们可以说每个人在编码超过10年后仍然是乞丐),那么先编写算法,然后编码。例如:

//Get user's choice
//If user choice is do stuff
    //Do stuff
//If it is do other stuff
    //Do other stuff
//If it is do another stuff
    //Do another stuff
//Else if he want to quit
    //Quit
然后变成

int choice=0, //User's choice
    end=0; //End of program

do
{
    //Get user's choice
    fprintf(stdout, "1:Do stuff\n2:Do other stuff\n3: Do another stuff\nX: end\n");
    while(fscanf(stdin, "%d", &choice) != 1){}
    //If user choice is do stuff
    if(choice == 1)
    {
        //Do stuff
    }
    //If it is do other stuff
    else if(choice == 1)
    {
        //Do other stuff
    }
    //If it is do another stuff
    else if(choice == 1)
    {
        //Do another stuff
    }
    //Else if he want to quit
    else
    {
        //Quit
        end = 1;
    }
}while (end == 0);
return 0;
它还可以防止您在几周后不知道为什么要这样做或那样做时对代码进行注释

六,。 日志,日志,日志,尤其是在调试时! 如果需要,可以将其放在stderr上,这样就可以将其与输出分离。 例如:

所以你知道你的程序现在在何时何地,这对调试是一个巨大的帮助

这就是我现在的想法,希望能对你有所帮助

另外,欢迎使用堆栈溢出

编辑:

多亏了chunk,还有一点很重要:

7.始终检查scanf是否有有效的用户输入。用户输入可以而且将是几乎所有的东西,并且在某个时候不会是您所想的,请始终测试它。(它不仅对(f)scanf有效,而且对从其他来源获取数据的所有方式都有效,但对您自己的源代码无效)

这样,除十进制数以外的任何其他输入都将被丢弃,并将关闭程序,当然您可以做得更好

int check = 0;
fprintf(stderr, "\tBegin loop\n");
fprintf(stdout, "1:Do stuff\n2:Do other stuff\n3: Do another stuff\nX: end\n");
while(fscanf(stdin, "%d", &choice) != 1)
{
    fprintf(stderr, "Bad input!\n");
}
fprintf(stderr, "\tValid choice is: %d\n", choice);

在此版本中,当用户键入无效内容时,他只需重试。

您需要在
继续之前编写
选择==2
选择==3
时的结果,如

fseek(fptr, -sizeof(customer), SEEK_CUR);
fwrite(&customer,sizeof(customer), 1, fptr);

除了DrakaSAN的答案之外,我还要补充一点,当您在接受整数输入之后进行字符/字符串输入时,您应该始终刷新输入缓冲区

刷新输入缓冲区的一种方法是使用
getchar()

while((ch=getchar())!='\n');

但是,如果用户将输入设为“123 abc\n”(如chux在注释中所述),假设123指向整数变量,“abc”指向字符数组,则有几种方法可以解决此问题:

//can be modified according to programmer's requirements
int a;
char arr[10],ch;

scanf("%d",&a);

while((ch=getchar())==' ' || ch=='\t' || ch=='\n') //loop until non-whitespace character
{
    if (ch=='\n')
    {
        ch=getchar();
        break;
    }
}

if (ch!='\n') //ch contains the first character of the character array
{
    arr[0]=ch;
    gets(arr+1);
}
else //if two consecutive new lines after integer, string contains nothing
    arr[0]='\0';

标题灼伤我的眼睛,还有短信试图用一个小代码重现你的问题。有了这个你会得到你的答案faster@nrathaus如果itz未检查,则jstStkOvrfl0w@Bartdude无限循环-可能这就是核心问题;)为什么不自己调试代码呢?我认为这是解决这个问题的方法。你应该知道如何调试在输入流上执行
fflush()
,比如
stdin
会导致UB。可能在某些平台上工作,但对于可移植代码来说是不好的做法。C11 7.21.5.2
fflush
函数“如果
stream
指向未输入最新操作的输出流或更新流,则
fflush
函数会导致将该流的任何未写入数据发送到主机环境中写入文件;否则,行为未定义。”我从未说过要使用
fflush()
。有几种方法可以刷新输入缓冲区。您可以使用
getchar()
在整数输入后清除缓冲区。我理解清除
stdin
的想法是丢弃当前
stdin
中的所有数据。也许您可以引用一些定义。您如何处理重定向的
stdin
?如何处理输入“123 abc\n“。既然这个答案是说使用flush和您的注释“我从来没有说过使用fflush()”,也许您应该发布它是如何实现的?请详细说明“您将如何处理输入”部分123 abc\n。“123 abc\n”是整数变量的输入还是字符数组的输入?两者都不是。使用code
fscanf(stdin,“%d”&choice)
,input
“123 abc\n”
应在“123”中扫描,并将
“abc\n”
留给下一个IO操作。采用整数输入并不总是意味着应丢弃(刷新)数字之后的所有内容。
scanf()的结果
未选中-IMHO,这是最重要的想法。如果用户输入了一个正确的数字“1”到“3”,然后输入了“X”,则此代码
int check = 0;
fprintf(stderr, "\tBegin loop\n");
fprintf(stdout, "1:Do stuff\n2:Do other stuff\n3: Do another stuff\nX: end\n");
while(fscanf(stdin, "%d", &choice) != 1)
{
    fprintf(stderr, "Bad input!\n");
}
fprintf(stderr, "\tValid choice is: %d\n", choice);
fseek(fptr, -sizeof(customer), SEEK_CUR);
fwrite(&customer,sizeof(customer), 1, fptr);
//can be modified according to programmer's requirements
int a;
char arr[10],ch;

scanf("%d",&a);

while((ch=getchar())==' ' || ch=='\t' || ch=='\n') //loop until non-whitespace character
{
    if (ch=='\n')
    {
        ch=getchar();
        break;
    }
}

if (ch!='\n') //ch contains the first character of the character array
{
    arr[0]=ch;
    gets(arr+1);
}
else //if two consecutive new lines after integer, string contains nothing
    arr[0]='\0';