-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathread_altitudes.c
126 lines (120 loc) · 2.74 KB
/
read_altitudes.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "terrain.h"
#define DELIMS "\n\r\t ,;"
#define TRUE 1
#define FALSE 0
/**
* read_altitudes - Open file and parse into 2d array of elevations
* @fname: name of file to open and read
* @saverows: variable passed into function call to hold the
* y-dimension from `fname`.
* @savecols: variable passed into function call to hold the
* x-dimension from `fname`.
*
* Return: pointer to heap-allocated 2d array of type `float3d_t` with each
* struct's `z` member initialized from `fname`.
*/
float3d_t **get_altitudes(char *fname, size_t *saverows, size_t *savecols)
{
FILE *altitudes;
float3d_t **coords;
char *line, *token, *saveptr;
size_t n, i, nrows, ncols, row, col, maxcols;
unsigned char uneven;
altitudes = fopen(fname, "r");
if (!altitudes)
{
perror("Failed to open file in read_altitudes");
exit(EXIT_FAILURE);
}
uneven = FALSE;
maxcols = 0;
nrows = 0;
line = NULL;
while (getline(&line, &n, altitudes) != -1)
{
nrows++;
token = strtok_r(line, DELIMS, &saveptr);
for (ncols = 0; token != NULL; ncols++)
token = strtok_r(NULL, DELIMS, &saveptr);
if (nrows == 1)
maxcols = ncols;
else if (ncols != maxcols)
{
uneven = TRUE;
if (ncols > maxcols)
maxcols = ncols;
}
}
coords = allocate_coords(nrows, maxcols);
if (!coords)
{
free(line);
fclose(altitudes);
exit(EXIT_FAILURE);
}
if (uneven)
fprintf(stderr,
"File [%s]: Uneven rows: padding with zeros...\n",
fname);
rewind(altitudes);
row = 0;
while (getline(&line, &n, altitudes) != -1)
{
token = strtok_r(line, DELIMS, &saveptr);
col = 0;
while (token)
{
coords[row][col].z = atof(token);
token = strtok_r(NULL, DELIMS, &saveptr);
col++;
}
row++;
}
free(line);
fclose(altitudes);
*saverows = nrows;
*savecols = maxcols;
return (coords);
}
/**
* allocate_coords - Allocate `nrows`x`ncols` array of `float3d_t` structs
* @nrows: number of rows to malloc
* @ncols: number of columns to malloc
*
* Return: 2d array of `float3d_t` structs, or NULL on failure
*/
float3d_t **allocate_coords(size_t nrows, size_t ncols)
{
float3d_t **coords;
size_t i;
coords = malloc(sizeof(float3d_t *) * nrows);
if (!coords)
{
perror("Could not malloc space for altitudes' rows");
return (NULL);
}
for (i = 0; i < nrows; i++)
{
coords[i] = calloc(ncols, sizeof(float3d_t));
if (!(coords[i]))
{
perror("Could not malloc space for altitudes' columns");
free_coords(coords, i);
return (NULL);
}
}
return coords;
}
/**
* free_coords - routine to free mallocated 2d array of `float3d_t` structs
* @coords: pointer to array to free
* @i: number of rows to free
*/
void free_coords(float3d_t **coords, size_t i)
{
if (coords == NULL || *coords == NULL)
return;
while (i)
free(coords[i--]);
free(coords);
}