在过去的3天里,我已经为家庭作业写了+删除+书面+已删除的代码,我在智慧结束时。这是我第一次被这个学期难倒,而且我开始有点疯狂了。
基本理念:
创建通用多项选择测验程序
问题将存储在结构中的文本文件中,如下所示:
问题
选择次数
选择本身(每个都在新行上)
正确答案
一切都很好,但是让我疯狂的是,每个问题的选择数量各不相同,而且它们都在同一个文件中。
有人可以看看我到目前为止的代码,并给我一些指导。 这是家庭作业,我不想要答案,只是一些帮助!
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _question {
char question[50];
int numChoices;
int numChoicesLine;
char choices[100][100];
char correctAns[50];
} Question;
void getQuestion (FILE file, int *firstLine) {
// init struct
Question q;
// array to store lines in the file
char lines[100][100];
int i = 0; // counter
// read all lines into lines array
while(fgets(lines[i], 100, &file))
{
// keep track of how many lines there are in the file
++i;
}
// i want j to reference the first line of each new question set
int j = *firstLine;
// get the question
strcpy(q.question, lines[j]);
printf("%s", q.question);
// get number of choices
for (int j = *firstLine; j < i; ++j)
{
// if the line is a number store that number into numChoices and which line of the file
// the number is found
if(atoi(lines[j]))
{
q.numChoices = atoi(lines[j]);
q.numChoicesLine = j;
break;
}
}
// store choices in array lines[k]
int k = 0;
for (k = q.numChoicesLine+1; k <= q.numChoices + 1; ++k)
{
// loop from the first choice to the last choice
fgets(lines[k], 100, &file);
strcpy(q.choices[k],lines[k]);
printf("-%s", q.choices[k]);
}
// store correct ans
// after the above loop, k refers to the line of the last choice in the quiz
strcpy(q.correctAns, lines[k]);
// set the firstLine to the line that stores the question for the next set
*firstLine = k + 1;
}
int main()
{
// open file
FILE *files;
files = fopen("tickle.txt", "r");
int firstLine = 0; // the first time it will be 0
getQuestion(*files, &firstLine);
return 0;
}
数据文件的示例:
谁是美国总统?
3
乔治布什
迈克尔乔丹 巴拉克奥巴马 巴拉克奥巴马墨西哥北部的哪个国家?
2
USA
加拿大
USA
答案 0 :(得分:2)
以下是一些有用的观点:
将getQuestion函数分解为几个较小的函数。尝试以准确表示函数功能的方式命名每个函数。
想想你可以写一次并重复使用的 helper / utility 函数。
考虑如何使代码更清晰,更易于阅读,理解,修改和维护。
代码如下:
void GetQuestion ()
{
DoStep1();
DoStep2();
DoStep3();
}
void DoStep1()
{
DoStep1A();
DoStep1B();
DoStep1C();
}
void DoStep2()
{
DoStep2A();
DoStep2B();
DoStep2C();
}
void DoStep3()
{
DoStep3A();
DoStep3B();
DoStep3C();
}
比这样的代码组织得更好:
void GetQuestion()
{
... // Step 1a
... // Step 1b
... // Step 1c
... // Step 2a
... // Step 2b
... // Step 2c
... // Step 3a
... // Step 3b
... // Step 3c
}
&#34; DoStep&#34;您的任何功能都可能不是一个好名字。我使用这些名称作为占位符,以便您可以弄清楚如何命名自己的函数。
答案 1 :(得分:1)
答案 2 :(得分:0)
促使你疯狂的最大交易之一是:
for (k = q.numChoicesLine+1; k <= q.numChoices + 1; ++k)
实际上,您从q.numChoicesLine+1
到q.numChoicesLine+q.numChoices
提取您的选择
让我们说你从第7行开始有3个选择,所以你需要使用for循环读取第7,8,9行:
for(i=7; i< 7+3; i++)
而不是
for(i=7; i<3; i++)
我的建议是像这样使用for循环:
for (k = q.numChoicesLine+1; k <= q.numChoicesLine+q.numChoices; ++k)
得到它?