Read a text file into a struct array with functions - c

so I have this file:
Jane
18
5.3
John
23
5.8
and I need to create a program to store this two persons details on a array of structs.
I have done this:
#include <stdio.h>
typedef struct
{
char name[100];
int age;
float height;
} PERSON;
main()
{
PERSON *X = NULL;
FILE *f;
char ch;
int lines = 1;
f = fopen("filename.txt", "r");
while ((ch = fgetc(f)) !=EOF)
{
if (ch == '\n')
lines++;
}
rewind(f);
X = (PERSON*) malloc ((lines/3) * sizeof(PERSON));
StoreInArray(X, f, lines);
}
StoreInArray(PERSON *X, FILE *f, int lines)
{
int i = 0;
for (i=0; i < lines/3; i++)
{
fscanf(f, "%s%d%f", (*(X+i)).name[100], &(*(X+i)).age, &(*(X+i)).height);
}
//for testing//
for (i=0; i < lines/3; i++)
printf("%s\n%d \n%f\n",X[i].name[100], X[i].age, X[i].height);
}
But all it prints is:
(null)
0
0.000000
If you could help me figure out what is wrong I'd be very appreciated!
Thank you in advance.

I'd compile with -Wall -O2 to catch warnings, which would have pointed out an error.
In your fscanf and printf, you don't want name[100] but name. You want to point to the name array, but name[100] is a single char [fetching past the end of the array (i.e.) undefined behavior], and would be flagged by the compiler.
Here's a version of your code with the bugs annotated/corrected:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[100];
int age;
float height;
} PERSON;
void StoreInArray(PERSON * X, FILE * f, int lines);
int
main()
{
PERSON *X = NULL;
FILE *f;
char ch;
int lines = 1;
f = fopen("filename.txt", "r");
while ((ch = fgetc(f)) != EOF) {
if (ch == '\n')
lines++;
}
rewind(f);
X = (PERSON *) malloc((lines / 3) * sizeof(PERSON));
StoreInArray(X, f, lines);
return 0;
}
void
StoreInArray(PERSON * X, FILE * f, int lines)
{
int i = 0;
for (i = 0; i < lines / 3; i++) {
#if 0
fscanf(f, "%s%d%f", (*(X + i)).name[100], &(*(X + i)).age, &(*(X + i)).height);
#else
fscanf(f, "%s%d%f", (*(X + i)).name, &(*(X + i)).age, &(*(X + i)).height);
#endif
}
//for testing//
for (i = 0; i < lines / 3; i++) {
#if 0
printf("%s\n%d \n%f\n", X[i].name[100], X[i].age, X[i].height);
#else
printf("%s\n%d \n%f\n", X[i].name, X[i].age, X[i].height);
#endif
}
}
Note that using *(X + i)).name is cumbersome, so here's a simplified and more readable version that uses an extra pointer variable:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[100];
int age;
float height;
} PERSON;
void StoreInArray(PERSON * X, FILE * f, int lines);
int
main()
{
PERSON *X = NULL;
FILE *f;
char ch;
int lines = 1;
f = fopen("filename.txt", "r");
while ((ch = fgetc(f)) != EOF) {
if (ch == '\n')
lines++;
}
rewind(f);
X = (PERSON *) malloc((lines / 3) * sizeof(PERSON));
StoreInArray(X, f, lines);
return 0;
}
void
StoreInArray(PERSON * X, FILE * f, int lines)
{
int i = 0;
PERSON *p;
p = X;
for (i = 0; i < lines / 3; i++, p++)
fscanf(f, "%s%d%f", p->name, &p->age, &p->height);
//for testing//
p = X;
for (i = 0; i < lines / 3; i++, p++)
printf("%s\n%d \n%f\n", p->name, p->age, p->height);
}
It isn't really necessary to preread the file to get a line count. It is possible to grow your array dynamically, as lines are read in, using realloc:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[100];
int age;
float height;
} PERSON;
int
main()
{
PERSON *X = NULL;
FILE *f;
int i;
PERSON *p;
int count = 0;
f = fopen("filename.txt", "r");
while (1) {
X = realloc(X,sizeof(PERSON) * (count + 1));
p = &X[count];
if (fscanf(f, "%s%d%f", p->name, &p->age, &p->height) == EOF)
break;
++count;
}
fclose(f);
// trim the array
X = realloc(X,sizeof(PERSON) * count);
p = X;
for (i = 0; i < count; i++, p++)
printf("%s\n%d \n%f\n", p->name, p->age, p->height);
return 0;
}
Here's a further refinement that reduces the number of realloc calls needed:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[100];
int age;
float height;
} PERSON;
int
main()
{
PERSON *X = NULL;
FILE *f;
int i;
PERSON *p;
size_t count = 0;
size_t alloc = 0;
f = fopen("filename.txt", "r");
while (1) {
if (count >= alloc) {
alloc += 100;
X = realloc(X,sizeof(PERSON) * alloc);
}
p = &X[count];
if (fscanf(f, "%s%d%f", p->name, &p->age, &p->height) == EOF)
break;
++count;
}
fclose(f);
// trim the array to what was actually used
X = realloc(X,sizeof(PERSON) * count);
p = X;
for (i = 0; i < count; i++, p++)
printf("%s\n%d \n%f\n", p->name, p->age, p->height);
return 0;
}

Related

Functions fopen/calloc/malloc and and ways of their replacement

I want to make a simple program (but difficult for me), which will find contacts by letters (parts of the name are entered using numbers) and by numbers (parts of the number). Input - numbers, from the standard input (txt file), output - contacts that contain these numbers (letters). The contact file looks like
(name)
(number)
(name)
(…)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (32)
/*
IN :
contacts.txt :
Sad Mirrow
38074025
Deniel Kovalski
78032596
Miky Trance
88055535
Martin Worried
77432651
96 [key number from standard entry]
OUT:
Deniel Kovalski
[because 96 matches in his number]
Martin Worried
[96 matches in his name Wo]
*/
typedef struct Contact {
char* name;
char* number;
} Contact;
char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
bool find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return true;
}
return false;
}
bool matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return true;
}
return false;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
size_t arrSize = 32;
Contact* contacts = malloc(arrSize * sizeof(Contact));
int k = 0;
size_t nameSize = MAX_NAME;
size_t numSize = MAX_NUM;
char *nameBuf = malloc(MAX_NAME);
char *numBuf = malloc(MAX_NUM);
FILE* f = fopen("contacts.txt", "r");
while (fgets(nameBuf, nameSize, f)
&& fgets(numBuf, numSize, f)){
contacts[k].name = malloc(MAX_NAME);
contacts[k].number = malloc(MAX_NUM);
strcpy(contacts[k].name, nameBuf);
strcpy(contacts[k].number, numBuf);
k++;
if (k == arrSize);
arrSize <<= 1;
contacts = realloc(contacts, arrSize * sizeof(Contact));
}
for (int i = 0; i < k; i++){
bool matchesName = matches(contacts[i].name, key);
bool matchesNumber = matches(contacts[i].number, key);
if (matchesName || matchesNumber)
printf("%s\n", contacts[i].name);
}
for (int i = 0; i < k; i++){
free(contacts[i].name);
free(contacts[i].number);
}
free(contacts);
free(nameBuf);
free(numBuf);
fclose(f);
return 0;
}
At first we did as we could. Then was a time to fulfill the conditions of the task and the problem came. It needs to be done without malloc/calloc/fopen. I tried to fix everything, but I ran into a problem that the program does not work and it seems to me that I'm confused.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (64)
struct Folio
{
char name[1000];
char num[1000];
};
static char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
int find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return 1;
}
return 0;
}
int matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
unsigned int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return 1;
}
return 0;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
struct Folio contacts[42]; //Entry entries[42]
int contacts_count = 0; //entries_count = 0;
//FILE* f = fopen("seznam.txt", "r");
char name[1000];
char num[1000]; //number[1000]
while (fgets(name, MAX_NAME, stdin) != NULL && fgets(num, MAX_NUM, stdin) != NULL)
{
// copy to struct
strcpy(contacts[contacts_count].name, name);
strcpy(contacts[contacts_count].num, num);
contacts_count++;
}
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[contacts_count].name, contacts[contacts_count].num);
}
//fclose(f);
return 0;
}
I want to ask the help of experienced programmers.
matchTable[10][9] is too small to save "7pqrsPQRS" as a string as needed in matchTable[j][i] != '\0';. Needs 10.
Suggest
//static char matchTable[10][9] = {
// "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
// "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
//};
static char *matchTable[10] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
Perhaps other issues too.
I believe the main issue is the the search logic. Code loops over all contacts, but will attempt a match against the a non-existing contacts entry.
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
...
Should this use the i-th contacts ?
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[i].name, key);
int matchesNumber = matches(contacts[i].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[i].name, contacts[contacts_count].num);
}
Or even
for (int i = 0; i < contacts_count; i++){
struct Folio con_p = &contacts[i] ;
int matchesName = matches(con_p->name, key);
int matchesNumber = matches(con_p->num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", con_p->name, con_p->num);
}
Also take a look at answer from chux - Reinstate Monica

Saving numbers from file to array in C

In my code I opened file (succesful) and I am trying to get the numbers to array, but it does not working (control output is bad). Compiler did not show me any error.
link on txt file: https://textuploader.com/1amip
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *fr_koty;
int **array = NULL;
int x = 1; /* Pocet radku */
int y = 1; /* Pocet sloupcu */
char line[1024];
char *assistant_line;
int number; /* Promena pro cislo*/
char *tab;
if((fr_koty = fopen("koty.txt", "r")) == NULL) {
printf("Soubor se nepodarilo otevrit!");
return 0;
}
while(fgets(line, 1023, fr_koty) != NULL) {
array = (int **) realloc(array, x * sizeof(int *));
array[x] = NULL;
assistant_line = line;
while(sscanf(assistant_line, "%d", &number) == 1) {
array[x] = (int *) realloc(array[x], y * sizeof(int));
array[x][y] = number;
printf("%d ", array[x][y]);
if((tab = strchr(assistant_line, '\t')) != NULL) {
assistant_line = tab + 1;
y++;
}
else {
break;
}
}
putchar('\n');
x++;
}
}
Output of numbers is random. I think the reason is bad working with memory, but I can not see the problem.
You're initializing x and y to 1, which is ok for the realloc, but as C arrays are 0 based, you need to use x-1 and y-1 to access the array elements.
Or you init them to 0 and use (x+1) and (y+1) in the realloc call. I would prefer this way.
Now I see it too. Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *fr_koty;
int **array = NULL;
int x = 1; /* Pocet radku */
int y; /* Pocet sloupcu */
char line[1024];
char *assistant_line;
int number; /* Promena pro cislo*/
char *tab;
if((fr_koty = fopen("koty.txt", "r")) == NULL) {
printf("Soubor se nepodarilo otevrit!");
return 0;
}
while(fgets(line, 1023, fr_koty) != NULL) {
y = 1;
array = (int **) realloc(array, x * sizeof(int *));
array[x-1] = NULL;
assistant_line = line;
while(sscanf(assistant_line, "%d", &number) == 1) {
array[x-1] = (int *) realloc(array[x-1], y * sizeof(int));
array[x-1][y-1] = number;
printf("%d ", array[x-1][y-1]);
if((tab = strchr(assistant_line, '\t')) != NULL) {
assistant_line = tab + 1;
y++;
}
else {
break;
}
}
putchar('\n');
x++;
}
}

Dynamically allocating array of structs C

I'm trying to make an array of structs in c, but I can't make it work. When I try to run it, the program crashes.
typedef struct{
char name[20];
char manufacturer[20];
unsigned int price;
} product;
unsigned int stringToNr(char *numbers){
unsigned int nr = 0;
unsigned int i;
for (i = 0; i < strlen(numbers); i ++)
{
nr *= 10; nr += numbers[i] - '0';
}
return nr;
}
I have a function that would print the list to a file, sometimes it reaches this function, sometimes it crashes before.
void printList(product *products, unsigned int nr){
unsigned int i;
FILE *f;
f = fopen("output.txt", "w");
for (i = 0; i < nr; i ++){
fprintf(f, "%s ", products[i].name);
fprintf(f, "%s ", products[i].manufacturer);
fprintf(f, "%d\n", products[i].price);
}
fclose(f);
}
I have to use a separate function to read the list from file.
void readList(product **products, unsigned int *nr){
FILE *f;
f = fopen("input.txt", "r");
char *row;
row = malloc(sizeof(char) * 45);
unsigned int rowLength;
fgets(row, 45, f);
rowLength = strlen(row);
if (row[rowLength - 1] == '\n'){
rowLength--;
row[rowLength ] = '\0';
}
*nr = stringToNr(row);
products = malloc((*nr) * sizeof(product*));
unsigned int i;
char *rowElement;
for (i = 0; i < *nr; i ++){
fgets(row, 45, f);
rowElement = strtok(row, " ");
strcpy((*products)[i].name, rowElement);
rowElement = strtok(NULL, " ");
strcpy((*products)[i].manufacturer, rowElement);
rowElement = strtok(NULL, " ");
rowLength = strlen(row);
if (row[rowLength- 1] == '\n'){
rowLength--;
row[rowLength] = '\0';
}
(*products)[i].price = stringToNr(rowElement);
}
free(row);
fclose(f);
}
Obviously the program has more features, but those work fine.
int main(){
product *products;
unsigned int nr;
readList(&products, &nr);
printList(products, nr);
free(products);
return 0;
}
My input file looks like this:
3
AAA FactoryA 300
BBB FactoryC 550
ZZZ Factory5 100
Code ignores value of products.
What ever readList() receives in products is overwritten with the malloc() call.
void readList(product **products, unsigned int *nr){
...
// bad
products = malloc((*nr) * sizeof(product*));
Instead, use *products. Also allocate by the size of the referenced variable, not by the size of the type. Easier to code, review and maintain.
*products = malloc(sizeof *(*products) * (*nr));
if (*products == NULL) Handle_OOM();
Minor: After fgets(row, ..., ...); , following is not safe from a hacker exploit of reading an initial null character.
rowLength = strlen(row);
// What happens when rowLength == 0
if (row[rowLength- 1] == '\n'){
...
Instead code could use below to rid the optional trailing '\n'.
row[strcspn(row, "\n")] = '\0';

fscanf() in C - need help reading a file using pointer notation

Spent an hour or two trying to debug this, but cannot figure out why it won't read my file correctly.
FILE *input;
int numAccounts = 7;
char **accountNames = malloc(sizeof(char)*numAccounts*10);
int *accountNumbers = malloc(sizeof(int)*numAccounts);
float *accountValues = malloc(sizeof(float)*numAccounts);
char *fileName = malloc(sizeof(char)*20);
input=fopen("input.txt","r");
int i;
for(i=0;i<numAccounts;i++) {
fscanf(input,"%s%d%f",*(accountNames+i),accountNumbers+i,accountValues+i);
printf("\n%s %d %f", *(accountNames+i), *(accountNumbers+i), *(accountValues+i));
}
fclose(input);
return 0;
And here is input.txt
Brown 1435 234.55
Dunn 2091 2011.75
Smith 8766 945.05
Stone 4530 0.0
Becker 9073 6235.75
Rich 1003 -42.00
Doe 6739 3655.80
Thank you!
You should start with non-dynamic allocation,
int main()
{
FILE *input = NULL;
int numAccounts = 7;
char accountNames[20] = "";
int accountNumbers = 0;
float accountValues = 0;
input=fopen("input.txt","r");
int i;
for(i=0;i<numAccounts;i++)
{
fscanf(input,"%s %d %f",accountNames,&accountNumbers,&accountValues);
printf("\n%s %d %f\n", accountNames, accountNumbers, accountValues);
}
fclose(input);
return 0;
}
If you must do dynamic allocation, then this pointer-to-pointer to char allocation is incorrect:
char **accountNames = malloc(sizeof(char)*numAccounts*10);
You'd need to allocate numAccounts of char * first, then for each char *, allocate 10 char. That can be done as follows:
char **accountNames = malloc(sizeof(char*)*numAccounts); // allocate numAccounts of char *
int i;
for( i=0; i < numAccounts; i++ )
{
*(accountNames + i) = malloc(sizeof(char)*10); // allocate 10 of char
}
So this should work:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *input = NULL;
int numAccounts = 7;
char **accountNames = malloc(sizeof(char*)*numAccounts); // allocate numAccounts of char *
int i;
for( i=0; i < numAccounts; i++ )
{
*(accountNames + i) = malloc(sizeof(char)*10); // allocate 10 of char
}
int *accountNumbers = malloc(sizeof(int)*numAccounts);
float *accountValues = malloc(sizeof(float)*numAccounts);
input=fopen("input.txt","r");
for(i=0; i<numAccounts; i++)
{
fscanf(input,"%s%d%f",*(accountNames+i), accountNumbers+i, accountValues+i);
printf("\n%s %d %f", *(accountNames+i), *(accountNumbers+i), *(accountValues+i));
}
fclose(input);
return 0;
}
If the account values are currency. You may want to save them as ints and divide by the lowest unity of that currency.
So instead of saving float accountValue = 23.25 as 23.25, save it as 2335 (23.25 * 100).
Then when you read it divide by 100 to get that value back.
float accountValueDollars;
int accountValueInCents;
fscanf(..., &accountValueInCents);
accountValueDollars = accountValueInCents / 100;
Also, you may want to consider saving in binary format, this way you don't have to worry about parsing the text.
typedef struct _account_t{
char name[50];
int account_number;
double amount;
} account_t;
int how_many = 0;
account_t * accounts = NULL;
// error checking skipped
fread(&how_many, 1, sizeof(int), input);
accounts = (account_t*)malloc(sizeof(account_t) * how_many);
for(int i = 0; i < how_many; i++){
fread(&accounts[i], 1, sizeof(account_t), input);
// print here or whatever
}
fclose(input);
NOTE: Untested code.

fscanf in a structure which has a string

I'm in trouble with my code.
I want to fscanf result.txt to structures, but it don't work;
result.txt format:
point name (for examples)
623 john
457 peter
312 chuck
etc.
First I count the lines then I malloc. For the structures' strings I have to malloc again, but I don't know the string's length. So I count it in the for loop.
#include <stdio.h>
#include <stdlib.h>
typedef struct ranklist {
int point;
char* name;
} ranklist;
int how_many_lines (FILE *fp){
rewind(fp);
int ch;
int line=0;
while (EOF != (ch = fgetc(fp)))
if (ch=='\n')
++line;
rewind(fp);
return line+1;
}
int how_many_letter(FILE *fp){
int ch;
int letter = 0;
int space=0;
while ('\n' != (ch = fgetc(fp)))
if (ch==' ')
space=1;
if (space == 1)
letter++;
return letter;
}
int main()
{
FILE *fp;
int y;
int name_length;
ranklist** r;
fp = fopen("result.txt","r");
int lines;
lines = how_many_lines(fp);
r = (ranklist**) malloc(lines * sizeof(ranklist*));
for (y = 0; y < lines; ++y){
name_length = how_many_letter(fp);
r[y] = (ranklist*) malloc(name_length * sizeof(ranklist));
}
for(y = 0; y < lines; y++){
fscanf(fp,"%d %s", &(r[y]->point), r[y]->name);
}
for( y = 0; y < lines; y++){
printf("%d %s", (r[y]->point), r[y]->name);
}
for (y = 0; y < lines; ++y)
free(r[y]);
free(r);
fclose(fp);
return 0;
}
sample to fix
int how_many_records(FILE *fp){
char ch;
int line=0;
int status;
rewind(fp);
while((status=fscanf(fp, "%*d %*[^\n]%c", &ch))==1)
++line;
if(status != EOF){
++line;
}
rewind(fp);
return line;
}
int how_many_letter(FILE *fp){
int letter = 0;
long pos = ftell(fp);
//fscanf(fp, " %*[^\n]%n", &letter);
fscanf(fp, " %*s%n", &letter);
fseek(fp, pos, SEEK_SET);
return letter;
}
int main(void){
FILE *fp = fopen("result.txt","r");
int y;
int name_length;
int lines = how_many_records(fp);
ranklist *r = malloc(lines * sizeof(*r));//just pointer, Do not need double pointer
for (y = 0; y < lines; ++y){
fscanf(fp, "%d", &r[y].point);
name_length = how_many_letter(fp);
r[y].name = malloc(name_length + 1);
fscanf(fp,"%s", r[y].name);
}
fclose(fp);
for( y = 0; y < lines; y++){
printf("%d %s\n", r[y].point, r[y].name);
free(r[y].name);
}
free(r);
return 0;
}
I did a few changes into your code and add some comments to explain. Just comment bellow any doubts.
int how_many_lines (FILE *fp){
rewind(fp);
int ch;
int line=0;
while (EOF != (ch = fgetc(fp)))
if (ch=='\n')
++line;
rewind(fp);
return line+1;
}
int how_many_letter(FILE *fp){
int ch;
int letter = 0;
// find first space since we
// know the input format <number> <name>
while ((ch = fgetc(fp)) != ' ');
// count the number of characters until end of file
// or '\n'
while ((ch = fgetc(fp)) != '\n' && ch != EOF )
letter++;
return (letter);
}
int main()
{
FILE *fp;
int y;
int name_length;
ranklist** r;
fp = fopen("file.txt","r");
int lines;
lines = how_many_lines(fp);
printf("[%d]\n", lines);
r = (ranklist**) malloc(lines * sizeof(ranklist*));
for (y = 0; y < lines; ++y){
name_length = how_many_letter(fp);
// you must allocate memory for ranklist element and string name
r[y] = (ranklist *) malloc(sizeof(ranklist));
r[y]->name = (char *) malloc(name_length * sizeof(char));
}
// rewind pointer again
rewind(fp);
for(y = 0; y < lines; y++){
fscanf(fp,"%d %s", &(r[y]->point), r[y]->name);
}
for( y = 0; y < lines; y++){
printf("%d %s\n", (r[y]->point), r[y]->name);
}
for (y = 0; y < lines; ++y)
free(r[y]);
free(r);
fclose(fp);
return 0;
}

Resources