有人能告诉我为什么这段代码跳到下一个输入

问题描述

我正在尝试读取学生数据(姓名、部门、​​卷、sgpa、cgpa),我使用 fgets 函数读取姓名和部门,但它跳到部门并且无法读取姓名。 这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[100];
    char department[50];
    int roll;
    float sgpa[12];
    float cgpa;
} Student;

void add(FILE *fp);
void modify(FILE *fp);
void display(FILE *fp);
FILE * del(FILE * fp);

int main(int argc,char **argv) {
    int option;
    FILE *fp;
    fp = fopen("db.txt","rb+");
    if (fp == NULL) {
        fp = fopen("db.txt","wb+");
        if (fp == NULL) {
            printf("Can't open the database");
            return 0;
        }
    }
    printf("\t1. Add Student");
    printf("\n\t2. Modify Student");
    printf("\n\t3. Show All Student");
    printf("\n\t4. Remove Student");
    printf("\n\tEnter Your Option :--> ");
    scanf("%d",&option);
    switch(option)
    {
        case 1:
            add(fp);
            break;
        case 2:
            // modify(fp);
            break;
        case 3:
            // display(fp);
            break;
        case 4:
            // fp = del(fp);
            break;
        default:
            printf("Unkonw option\n");
    }
    return 0;
}

void add(FILE *fp) {
    Student std;
    int i;
    float cgpa;
    fseek(fp,SEEK_END);
    printf("\n\tEnter Full Name of Student: ");
    fflush(stdin);
    fgets(std.name,100,stdin);
    std.name[strlen(std.name)-1]='\0';
    printf("\n\tEnter Depertment Name: ");
    fflush(stdin);
    fgets(std.department,50,stdin);
    std.department[strlen(std.department)-1]='\0';
    printf("\n\tEnter Roll number: ");
    scanf("%d",&std.roll);
    printf("\n\tEnter SGPA for 12 semesters\n");
    for(i=0,cgpa=0; i<12; i++)
    {
        scanf("%f",&std.sgpa[i]);
        cgpa+=std.sgpa[i];
    }
    cgpa/=12.0;
    std.cgpa=cgpa;
    fwrite(&std,sizeof(std),1,fp);
}

解决方法

Is there a way of limiting scanf in C?

我这样做了,如果您在字符串输入方面遇到很多问题,请注意我的其他答案可能会对您有所帮助

这里有一个更具体的答案,可以解决您在输入和 StringInput 之前放置要打印的消息的问题,并放置用于保存消息的数组 我希望这有效,因为您也为此使用了一个数组

我也看到了:

fp = fopen("db.txt","rb+");
    if (fp == NULL) {
        fp = fopen("db.txt","wb+");
        if (fp == NULL) {
            printf("Can't open the database");
            return 0;
        }
    }

这可能不是你想要的,因为如果它因为使用 wb+ 突然出现故障而失败,你会覆盖它

“r+” – 搜索文件。打开文件以进行读取和写入。如果成功打开, fopen() 将其加载到内存中并设置一个指向其中第一个字符的指针。如果无法打开文件,则返回 NULL。

“w+” – 搜索文件。如果文件存在,则覆盖其内容。如果文件不存在,则会创建一个新文件。如果无法打开文件,则返回 NULL。

FUNCAUX_MAX_STRING 是一个宏,您可以这样定义它:

#define FUNCAUX_MAX_STRING 100

这使得数字或元素为 100,您只需更改一次值即可轻松更改使用宏的每个数字

void readString(char message[FUNCAUX_MAX_STRING],char StringInput[FUNCAUX_MAX_STRING],int maxChars)
{
    int sizeString;

    do          // Repete leitura caso sejam obtidas strings vazias
    {
        printf("%s",message);
        fgets(StringInput,maxChars,stdin);

        sizeString = strlen(StringInput);

        if (sizeString == 1)
        {
             printf("Nao foram introduzidos caracteres!!! . apenas carregou no ENTER \n\n");  
        }

    }
    while (sizeString == 1);

    if(StringInput[sizeString-1] != '\n') 
    {
        cleanBufferStdin(); 
    }
    else
    {
        StringInput[sizeString-1] = '\0';   
    }

}
void cleanBufferStdin(void)
{
    char chr;
    do
    {
        chr = getchar();
    }
    while (chr != '\n' && chr != EOF);
}