1

我需要构建一个指向动态分配结构(DBrecord)的指针数组,并用另一个文件的输入填充该数组。不知道如何解决这个问题。

数据文件将首先具有条目数,然后是特定顺序的条目。

条目数

lastName firstName studentID year gpa expGradYear

例子:

1

能源部约翰 12345678 高级 3.14159 2015

这是我到目前为止的代码:

类.h

typedef enum {firstYear, sophomore, junior, senior, grad} class;

主程序

#include <stdio.h>
#include <stdlib.h>
#include "class.h"

int main(){

//DBrecord is name for structure
struct DBrecord{
int DBrecordID;     //ID for each entry, range 0-319
char *last;         //student last name
char *first;        //student first name
char studentID[8];  //student ID
int age;            //student age
class year;         //year in school
float gpa;          //GPA
int expGradYear;    //expected graduation year
};
int numEntries;     //total number of entries, first num in data file
struct DBrecord **ptrToDB;

//scan first int in data file and assign to numEntries
scanf("%d", &numEntries);

//allocate memory for structures, each is 36 bytes
*ptrToDB = malloc (sizeof(struct DBrecord) * numEntries);

//free allocated memory
free(ptrToDB);

//build an array of pointers to dynamically allocated structures
//fill that array with input from data file

//build 7 arrays of pointers to DBrecords, one for each field except DB ID
//sort each a different way
//note the 7 arrays are pointers, no copying

//print each of the 7 sorted arrays

return 0;
}
4

2 回答 2

3

我可以给你一些关于如何看待这个问题的片段。

首先 - 我会避免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然后你在字符串中有你想要的文件名。

于 2012-04-09T17:07:04.583 回答
1

从哪里开始,从哪里开始......

//allocate memory for structures, each is 36 bytes
mem = (double *)malloc(36*numEntries);
  1. malloc 应该是malloc (sizeof (struct DBRecord) * numEntries);
  2. 不要转换 malloc
    2a 的结果。你忘了stdlib.h
  3. 为什么包括class.h
  4. 你的指针数组不是double,而是

    struct DBRecord **ptrToDB;
    *ptrToDB = malloc (sizeof (struct DBRecord) * numEntries);
    

这应该让你开始。

接下来,free()应该是您在离开函数之前做的最后一件事(是的,main 是一个函数)

你必须为下一部分插入一些代码,我不能为你做作业。

于 2012-04-09T16:31:25.913 回答