这是我的代码的一部分:
问题:它会跳过&#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.");
}
答案 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.");
}