C - 构建动态分配的指针数组,填充到文件输入的结构 [英] C - Build dynamically allocated array of pointers to structures filled with input from file

查看:179
本文介绍了C - 构建动态分配的指针数组,填充到文件输入的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to build an array of pointers to dynamically allocated structures (DBrecord) and fill that array with input from another file. Not sure how to approach this.

数据文件将首先输入条目,后面是特定顺序的条目。

The data file will have the number of entries first, followed by entries in a specific order.

numOfEntries

numOfEntries

lastName firstName studentID year gpa expGradYear

lastName firstName studentID year gpa expGradYear

示例:

1

Doe John 12345678 senior 3.14159 2015

Doe John 12345678 senior 3.14159 2015

这是代码我到目前为止:

Here's the code I have so far:

class.h

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

main.c

#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;
}


推荐答案

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

I can give you some snippets on how to look at this problem.

首先 - 我会避免使用 class 名称为任何变量,因为在许多面向对象的编程语言(包括C ++)它是一个关键字,不能是变量的名称。

First - I would avoid using class name for any variable, because in many object-oriented programming languages (including C++) it is a keyword and can't be a name of variable.

使用typedef可能是个好主意。那么你可以声明一个struct变量而不使用struct DBrecord,只是DBrecord。但这是可选的。这是它的外观:

It might be a good idea to use typedef. Then you could declare a struct variable without using "struct DBrecord", just "DBrecord". But that's optional. This is how it would look:

typedef struct {
   int DBrecordID; // ID for each entry
   char *lastName;
   char *firstName;
   char studentID[8];
   ...
} DBrecord;



从文件加载



您有文件开头的记录数,所以您不需要额外关心它。只需加载它。

Loading from file

In this homework you have the number of records at the beginning of the file, so you don't need to take "extra" care about it. Just load it.

我们假设文件是​​这样的:

Let's assume the file is like this:

2
Doe John 12345678 senior 3.14159 2015
Carl Boss 32315484 junior 2.71 2013

因此,您首先使用文件打开它。

Therefore the first thing you do with your file is to open it.

使用文件的便携式方法是使用FILE指针。让我看看( stdio.h 必须包含在内):

Portable way of working with files is by using FILE pointer. Let me show it (stdio.h must be included):

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()方式读取字符。这是你如何读取记录数(记住它在第一行,我们刚刚打开文件 - 我们在文件的开头):

Then you can read from your file by line using fgets() to read by lines or fgetc() to read by characters. This is how you can read number of records (remember that it's on the first line and we've just opened the file - we are at the beginning of the file):

char buffer[100]; // Define the buffer
fgets(buffer, 100 /* size of buffer */, filePtr);

现在缓冲区包含第一行(不含\\\
字符) - 记录数。继续将num的字符转换为整数(这里 stdlib.h 也必须包含在内):

Now buffer contains the first line (without \n character) - number of records. Continue with converting the num's characters into integer (here stdlib.h also has to be included):

int numOfRecords = atoi(buffer);



分配足够的DBrecords



现在你知道记录的数量,您可以为它们分配足够的空间。我们将使用数组的指针。

Allocating enough DBrecords

Now you know the number of records, you can allocate enough space for them. We will use array of pointers.

DBrecord **recs;
recs = (DBrecord **) malloc(sizeof(DBrecord *) * numOfRecords);

现在我们创建了指针数组,所以现在我们需要将每个单独的指针分配为DBrecord。使用循环:

Now we have created array of pointers, so now we need to allocate every individual pointer as a DBrecord. Using cycle:

int i;
for(i = 0; i < numOfRecords; i++)
{
   recs[i] = (DBRecord *) malloc(sizeof(DBrecord));
}

现在,您可以像这样访问数组元素(=个别记录):

Now you can acces array elements (= individual records) like this:

recs[0]->lastname /* two possibilities */
*(recs[0]).lastname

an so。

现在,您已经了解完成作业的一切。这样你可以填充数组:

Now you know everything to get the homework done. This way you fill the array:

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 */
}



Is it somehow clearer now?

通常有两个将参数(值)传递给程序的方式。他们是:

There are usually two ways of 'passing' arguments (values) to a program. They are:

./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`.

如果可以选择,我强烈建议您第二个。因此,您需要主要定义为:

If you can choose, I strongly recommend you the second one. Therefore you need to have main defined as this:

int main(int argc, char *argv[])  // this is important!
{
   // code

   return 0;
}

argc 其中说,有多少论据被传递给该计划。 argv 是存储它们的数组。请记住,第一个参数是程序的名称。因此,如果您需要检查,请执行以下操作:

argc is integer which says, how much arguments were passed to the program. argv is array storing them. Remember, that the first argument is name of the program. Therefore if you need to check for it, do it:

if(argc != 2)
{
  printf("Number of arguments is invalid\n");
  exit(1); // exit program
}

然后你只需要 argv [ 1] into fopen 函数,而不是字符串records.txt。

Then you only put argv[1] into fopen function, instead of the string "records.txt".

如果通过将记录文件的名称传递给程序,则必须执行另一种方法。 /程序< records.txt ,这意味着records.txt(不含引号)将被传递(重定向)到程序的标准输入。

Another approach must be done, if the name of the records file is passed to the program via ./program < records.txt, which means that "records.txt" (without quotes) will be passed (redirected) to program's standard input.

因此要处理这个,你可以这样做:

Therefore to handle that, you can do this:

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 string。

Then you have your desired file's name in filename string.

这篇关于C - 构建动态分配的指针数组,填充到文件输入的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆