为什么我无法输入我的名字?

时间:2016-03-18 08:39:41

标签: c

这是我的代码的一部分:

问题:它会跳过&#34的输入;请输入您的姓名"到"请输入你的分数"

我尝试了什么: flushall(); _flushall(); - 昨天以某种方式工作,并尝试将这些功能放在printf,scanf ..

之间
student *Create_Class(int size) {
    int i, j;
    int idStud, nameStud, markStud;

    student *classStudent;
    classStudent = (student*)malloc(size * sizeof(student));

    for (i = 0; i < size; i++) {
        classStudent[i].name = (char*)malloc(51 * sizeof(char));
        int numOfmarks = 4;

        printf("Please enter your name: ");
        gets(classStudent[i].name);
        _flushall(); //tried _flushall() and it worked yesterday.. tried fflush(NULL) too.
        printf("\nPlease enter 4 marks: ");

        for (j = 0; j < numOfmarks; j++) {
            scanf("%d", &classStudent[i].marks[j]);

        }
        Avg_Mark(&classStudent[i]);
    }
    return classStudent;
}

编辑:(完整代码)

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

typedef struct {
    char *name;
    int marks[4];
    float avg;
} student;

student *Create_Class(int);
void Avg_Mark(student*);
void Print_One(student*);
void exStudents(student *s, int size);


int main() {
    int size, i;
    student *arr;
    printf("\nEnter the number of students: \n");
    scanf("%d", &size);

    arr = Create_Class(size);
    exStudents(arr, size);

    for (i = 0; i < size; i++)
        free(arr[i].name);

    free(arr);
    getch();
}

student *Create_Class(int size) {
    int i, j;
    int idStud, nameStud, markStud;

    student *classStudent;
    classStudent = (student*)malloc(size * sizeof(student));

    for (i = 0; i < size; i++) {
        classStudent[i].name = (char*)malloc(51 * sizeof(char));
        int numOfmarks = 4;
        int sizeOfName;

        printf("Please enter your name: \n");
        _flushall();
        fgets(classStudent[i].name,50,stdin);
        sizeOfName = strlen(classStudent[i].name);
        printf("Please enter 4 marks: ");
        for (j = 0; j < numOfmarks; j++) {
            scanf("%d", &classStudent[i].marks[j]);
        }
        Avg_Mark(&classStudent[i]);
    }
    return classStudent;
}

void Avg_Mark(student *s) {
    int i, numOfMarks = 4, sum = 0;

    for (i = 0; i < numOfMarks; i++) {
        sum += s->marks[i];
    }
    s->avg = (sum / 4.0);
}

void Print_One(student *s) {
    printf("The average of %s is %f", s->name, s->avg);
}

void exStudents(student *s, int size) {
    int flag = 1;

    while (size > 0) {
        if (s->avg > 85) {
            Print_One(s);
            flag = 0;
        }
        s++;
        size--;
    }
    if (flag)
        printf("\n There're no students with above 85 average.");
}

3 个答案:

答案 0 :(得分:0)

正如您在评论中已经说过的那样,解决方案是使用两步法:首先读取行,然后根据需要扫描这些行。这反映了用户将如何回答您的提示,即提供信息然后按回车。

这是您的代码的变体。我还更改了main函数,因为它还使用了scanf,并且我添加了一个函数来从fgets输入的字符串中去除空格。 (此函数需要<ctype.h>标题。)

#include <ctype.h>

int main()
{
    char line[80];
    int size, i;

    puts("Enter the number of students:");
    if (fgets(line, sizeof(line), stdin) == NULL) exit(1);

    if (sscanf(line, "%d", &size) == 1 && size > 0) {
        student *arr = Create_Class(size);

        exStudents(arr, size);

        for (i = 0; i < size; i++) free(arr[i].name);
        free(arr);
    }

    return 0;
}

/*
 *      strip white space from beginning and end of string
 */
char *strip(char *str)
{
    size_t l = strlen(str);

    while (l > 0 && isspace((unsigned char) str[l - 1])) l--;
    str[l] = '\0';

    while (isspace((unsigned char) *str)) str++;
    return str;
}

/*
 *      Create students and prompt user for input
 */
student *Create_Class(int size)
{
    int i;

    student *classStudent = malloc(size * sizeof(student));

    for (i = 0; i < size; i++) {
        char line[80];
        char *p;
        int okay = 0;

        puts("Please enter your name:");
        if (fgets(line, sizeof(line), stdin) == NULL) exit(1);
        p = strip(line);

        classStudent[i].name = malloc(strlen(p) + 1);
        strcpy(classStudent[i].name, p);

        while (!okay) {
            int j = 0;

            okay = 1;
            puts("Please enter 4 marks:");
            if (fgets(line, sizeof(line), stdin) == NULL) exit(1);

            p = line;
            while (p && j < 4) {
                char *tail;
                int m = strtol(p, &tail, 10);

                if (p == tail) break;

                if (m < 1 || m > 100) {
                    puts("Illegal mark.");
                    okay = 0;
                }

                classStudent[i].marks[j++] = m;
                p = tail;
            }

            if (j < 4) {
                printf("Expected 4 marks, but got %d.\n", j);
                okay = 0;                
            }
        }

        Avg_Mark(&classStudent[i]);
    }

    return classStudent;
}

请不要在没有理由的情况下冲洗缓冲液。写入换行符时,会刷新stdout,因此请务必使用换行终止所有字符串。字符串开头而不是末尾的新行是不整齐输出的标志。

答案 1 :(得分:0)

代码中的问题是scanf不会消耗用户在以下位置返回的新行:

scanf("%d", &size);

所以当程序到达时:

fgets(classStudent[i].name,50,stdin);

在用户输入任何内容之前,会收到stdin中剩余的新行。 解决方案是用fgets和atoi调用替换初始scanf调用。

char size_str[5];
fgets(size_str,5,stdin);
size = atoi(size_str);

fgets和sscanf的组合通常也能很好地处理用户输入然后转换它。

使用sscanf的变体是:

char size_str[5];
fgets(size_str,5,stdin);
sscanf(size_str,"%d\n",&size);

请注意,如果输入的值太大,则可以安全地停止程序。这里允许从0到999。

另请注意,您必须对下面的某些行进行相同的更改。

而不是:

        scanf("%d", &classStudent[i].marks[j]);

写:

        char mark_str[5];
        fgets(mark_str,5,stdin);
        sscanf(mark_str,"%d\n",&classStudent[i].marks[j]);

希望这有帮助。

答案 2 :(得分:0)

<强> SOLUTION:

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

typedef struct { //struct decleration
    char *name;
    int marks[4];
    float avg;
} student;

//functions decleration
student *Create_Class(int);
void Avg_Mark(student*);
void Print_One(student*);
void exStudents(student *s, int size);


int main() {
    /*variable declerations*/
    int i, size;
    char line[80];
    student *arr;

    /*Input number of students*/
    printf("\nEnter the number of students: \n");
    fgets(line, sizeof(line), stdin);
    sscanf(line, "%d", &size);

    /*Get name of students, marks, and calculate average above 85*/
    arr = Create_Class(size);
    exStudents(arr, size);

    /*Free memory*/
    for (i = 0; i < size; i++)
        free(arr[i].name);
    free(arr);

    getch();
}

student *Create_Class(int size) { /*Get names of each student, and their 4 marks.*/
    /*Variable declerations*/
    int i, j;
    char line[51];
    student *classStudent;

    /*Dynamic allocation to assign structure to every student*/
    classStudent = (student*)malloc(size * sizeof(student));

    /*Get name of students and their 4 marks*/
    for (i = 0; i < size; i++) {

        /*Variable decleration and dynamic allocation of 51 chars*/
        classStudent[i].name = (char*)malloc(51 * sizeof(char));
        int numOfmarks = 4;
        int sizeOfName;

        /*Input name of student*/
        printf("Please enter your name: \n");
        scanf("%s", classStudent[i].name);

        /*Input marks of student*/
        printf("Please enter 4 marks: ");
        for (j = 0; j < numOfmarks; j++) {
            scanf("%d", &classStudent[i].marks[j]);
        }
        /*Calculate average, and print averages of students above 85*/
        Avg_Mark(&classStudent[i]);
    }
    return classStudent;
}

/*Calculate averages of students*/
void Avg_Mark(student *s) {
    int i, numOfMarks = 4, sum = 0;

    for (i = 0; i < numOfMarks; i++) {
        sum += s->marks[i];
    }
    s->avg = (sum / 4.0);
}

/*Print average (if bigger than 85)*/
void Print_One(student *s) {
    printf("The average of %s is %0.1f\n", s->name, s->avg);
}
/*Check whether the average is bigger than 85*/
void exStudents(student *s, int size) {

    int flag = 1; //flag to check if there are any students with avg above 85

    while (size > 0) {
        if (s->avg > 85) {
            Print_One(s); //Print the average
            flag = 0; //We found atleast one student with avg > 85
        }
        s++; //Advance to next student
        size--;
    }
    if (flag)
        printf("\n There're no students with above 85 average.");
}
相关问题