我可以给你一些关于如何看待这个问题的片段。
首先 - 我会避免class
对任何变量使用名称,因为在许多面向对象的编程语言(包括 C++)中,它是一个关键字,不能是变量的名称。
结构 DBrecord
使用 typedef 可能是个好主意。然后你可以声明一个结构变量而不使用“struct DBrecord”,只使用“DBrecord”。但这是可选的。这是它的样子:
typedef struct {
int DBrecordID; // ID for each entry
char *lastName;
char *firstName;
char studentID[8];
...
} DBrecord;
从文件加载
在这个作业中,您在文件开头有记录数,因此您无需“额外”关心它。只需加载它。
假设文件是这样的:
2
Doe John 12345678 senior 3.14159 2015
Carl Boss 32315484 junior 2.71 2013
因此,您对文件所做的第一件事就是打开它。
处理文件的可移植方式是使用 FILE 指针。让我展示一下(stdio.h
必须包括在内):
FILE *filePtr; // Define pointer to file
if((filePtr = fopen("records.txt", "r")) == NULL) // If couldn't open the file
{
printf("Error: Couldn't open records.txt file.\n"); // Printf error message
exit(1); // Exit the program
}
然后,您可以使用 fgets() 逐行读取或 fgetc() 逐行读取文件,以逐行读取文件。这是您可以读取记录数的方式(请记住,它在第一行,我们刚刚打开了文件 - 我们在文件的开头):
char buffer[100]; // Define the buffer
fgets(buffer, 100 /* size of buffer */, filePtr);
现在缓冲区包含第一行(没有 \n 字符) - 记录数。继续将 num 的字符转换为整数(这里stdlib.h
也必须包括在内):
int numOfRecords = atoi(buffer);
分配足够的 DBrecords
现在您知道了记录的数量,您可以为它们分配足够的空间。我们将使用指针数组。
DBrecord **recs;
recs = (DBrecord **) malloc(sizeof(DBrecord *) * numOfRecords);
现在我们已经创建了指针数组,所以现在我们需要将每个单独的指针分配为一个 DBrecord。使用周期:
int i;
for(i = 0; i < numOfRecords; i++)
{
recs[i] = (DBRecord *) malloc(sizeof(DBrecord));
}
现在您可以像这样访问数组元素(= 单个记录):
recs[0]->lastname /* two possibilities */
*(recs[0]).lastname
依此类推。
用文件中的值填充数组
现在你知道了完成作业的一切。这样你填充数组:
int i;
for(i = 0; i < numOfRecords; i++)
{
// Content of cycle reads one line of a file and parses the values into recs[i]->type...
/* I give you small advice - you can use fgetc(filePtr); to obtain character by character from the file. As a 'deliminer' character you use space, when you hit newline, then the for cycle continues.
You know the order of stored values in the file, so it shouldn't be hard for you.
If you don't get it, let me now in comments */
}
现在是不是更清楚了?
编辑:文件名作为主要参数
通常有两种方法可以将参数(值)“传递”给程序。他们是:
./program < records.txt // Here the file's name is passed to program on stdin
./program records.txt // Here the file's name is passed as value in `argv`.
如果你可以选择,我强烈推荐你第二个。因此,您需要将 main 定义为:
int main(int argc, char *argv[]) // this is important!
{
// code
return 0;
}
argc
是整数,表示传递给程序的参数数量。argv
是存储它们的数组。请记住,第一个参数是程序的名称。因此,如果您需要检查它,请执行以下操作:
if(argc != 2)
{
printf("Number of arguments is invalid\n");
exit(1); // exit program
}
然后你只argv[1]
输入fopen
函数,而不是字符串“records.txt”。
编辑 2:从标准输入读取文件名
如果记录文件的名称通过 传递给程序,则必须采用另一种方法./program < records.txt
,这意味着“records.txt”(不带引号)将被传递(重定向)到程序的标准输入。
因此,要处理这个问题,您可以这样做:
char filename[50]; // buffer for file's name
scanf("%s", &filename); // reads standard input into 'filename' string until white character appears (new line, blank, tabulator).
filename
然后你在字符串中有你想要的文件名。