Skip to content

Commit 8921b7f

Browse files
committed
CPSC223
1 parent e43ed46 commit 8921b7f

30 files changed

+6303
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
2+
3+
// to do:
4+
// make work with stdin
5+
6+
// Jacob Lessing
7+
// CPSC 223 Fall 2022
8+
9+
// This program parses a GPX File, outputing
10+
// location, and time data for each trkpt
11+
12+
#include <stdio.h>
13+
#include <stdlib.h>
14+
#include <string.h>
15+
#include <ctype.h>
16+
17+
// how many characters from stdin the program "remembers" as it scans
18+
// 10 is sufficient as its larger than any attribute or tag name of interest
19+
#define BUFFER_SIZE 10
20+
21+
int scan_for_attribute(char attribute[]);
22+
int scan_for_start_tag(char element_type[]);
23+
int print_attribute_value();
24+
int print_element_text();
25+
26+
int scan_for_string(char target[], int ignore_quotes, int case_insensitive);
27+
28+
int main()
29+
{
30+
// repeatedly scan for additional trkpt elements to parse
31+
while (1) {
32+
// will close file and exit program if no more trkpt elements are found
33+
if (scan_for_start_tag("<trkpt")) {
34+
return 0;
35+
}
36+
37+
// scans, parses, and prints children and fields of trkpt
38+
scan_for_attribute(" lat");
39+
print_attribute_value();
40+
printf(",");
41+
42+
scan_for_attribute(" lon");
43+
print_attribute_value();
44+
printf(",");
45+
46+
scan_for_start_tag("<ele");
47+
print_element_text();
48+
printf(",");
49+
50+
scan_for_start_tag("<time");
51+
print_element_text();
52+
printf("\n");
53+
}
54+
}
55+
56+
57+
// ************************************ //
58+
// SCANNING FUNCTIONS //
59+
// ************************************ //
60+
61+
62+
// pre: atribute should be atribute name WITHOUT appended =
63+
// post: reads stdin stream until TARGET ATRIBUTE is found
64+
// returns 0 if target is found
65+
// returns 1 if end of file is reached without match
66+
int scan_for_attribute(char attribute[]) {
67+
int returned_value;
68+
char curr_char;
69+
70+
// 1: scan for attribute name, but ignore matches inside quotes
71+
// 0: make search case sensitive
72+
returned_value = scan_for_string(attribute, 1, 0);
73+
74+
if (returned_value) return 1; // end of file (EOF)
75+
else {
76+
if (fscanf(stdin, " %c", &curr_char) <= 0) return 1; // (EOF)
77+
if (curr_char == '=') return 0; // target found
78+
else scan_for_attribute(attribute); // otherwise, search again
79+
}
80+
81+
return 1;
82+
}
83+
84+
// pre: takes element type preceeded by <
85+
// post: scans stdin stream until desired tag is found
86+
// returns 0 if target is found
87+
// returns 1 if end of file is reached without match
88+
int scan_for_start_tag(char element_type[]) {
89+
int returned_value;
90+
char curr_char;
91+
92+
// 1: scan for attribute name, but ignore matches inside quotes
93+
// 1: make search case insensitive
94+
95+
returned_value = scan_for_string(element_type, 1, 1);
96+
97+
// checks that identified attribute name is followed by ' ' or '>'
98+
if (returned_value) return 1; // end of file (EOF)
99+
else {
100+
if (fscanf(stdin, "%c", &curr_char) <= 0) return 1; // (EOF)
101+
if (curr_char == ' ' || curr_char == '>') {
102+
// re-add char to stream so it can be used later
103+
if (curr_char == '>') ungetc('>', stdin);
104+
if (curr_char == ' ') ungetc(' ', stdin);
105+
return 0; // target found
106+
}
107+
else scan_for_start_tag(element_type); // otherwise, search again
108+
}
109+
110+
return 1;
111+
}
112+
113+
114+
// ************************************ //
115+
// PRINTING FUNCTIONS //
116+
// ************************************ //
117+
118+
// pre: attribute must be first thing in quotes
119+
// post: prints next attribute value
120+
// returns 0 if full value is sucessfully printed
121+
// returns 1 if file ends before closing "/' is encountered
122+
int print_attribute_value() {
123+
char curr_char;
124+
125+
// value can be enclosed in " or '
126+
char enclosing_char;
127+
128+
// used as a boolean to indicate a state:
129+
// 1 indicates stdin is inside an atribute value
130+
// 0 indicates stdin is outside any atribute value
131+
int is_inside_value = 0;
132+
133+
while (fscanf(stdin, "%c", &curr_char) > 0) {
134+
switch (is_inside_value) {
135+
case 0:
136+
// search for start of attribute value
137+
if (curr_char == '"' || curr_char == '\'') {
138+
is_inside_value = 1;
139+
enclosing_char = curr_char;
140+
}
141+
break;
142+
case 1:
143+
// print characters until final quote is reached
144+
if (curr_char == enclosing_char) return 0;
145+
else if (curr_char == ',') printf("&comma");
146+
else printf("%c", curr_char);
147+
148+
break;
149+
}
150+
}
151+
152+
// end of file reached
153+
return 1;
154+
155+
}
156+
157+
// pre: element has no children & stdin is in start tag of desired element
158+
// post: prints the element text of the current element
159+
// returns 0 if full value is sucessfully printed
160+
// returns 1 if file ends before printing is complete
161+
int print_element_text() {
162+
// >, outside of any string, marks end of start tag
163+
if (scan_for_string(">", 1, 0)) return 1;
164+
165+
// print all characters until start of end tag <
166+
char curr_char;
167+
while (fscanf(stdin, "%c", &curr_char) > 0) {
168+
if (curr_char == '<') return 0;
169+
else if (curr_char == ',') printf("&comma");
170+
else printf("%c", curr_char);
171+
}
172+
173+
// end of file reached without closing ">"
174+
return 1;
175+
}
176+
177+
178+
// ************************************ //
179+
// HELPER FUNCTIONS //
180+
// ************************************ //
181+
182+
183+
// post: reads stdin stream until TARGET string is found
184+
// returns 0 if target is found
185+
// returns 1 if end of file is reached without match
186+
// ignores characters in quotes when flag ignore_quotes == 1
187+
// executes case-insensitive search when flag case_insensitive == 1
188+
int scan_for_string(char target[], int ignore_quotes, int case_insensitive)
189+
{
190+
// stores BUFFER_SIZE most recent characters from input stream
191+
192+
// *** I wanted to initialize my buffer like this, but
193+
// the code didn't work as a I expected ***
194+
//char buffer[BUFFER_SIZE + 1];
195+
//buffer[BUFFER_SIZE] = '\0';
196+
char buffer[] = "xxxxxxxxxx";
197+
198+
// most recently read char from input
199+
char curr_char;
200+
201+
while (fscanf(stdin, "%c", &curr_char) > 0) {
202+
203+
// checks if character is quote, and skips quote if ignore_quotes == 1
204+
if (ignore_quotes && (curr_char == '"' || curr_char == '\'')) {
205+
// flushes buffer
206+
for (size_t i = 0; i < BUFFER_SIZE; i++) {
207+
buffer[i] = '`'; // garbage character
208+
}
209+
210+
// identifies if " or ' started quote
211+
char enclosing_char = curr_char;
212+
213+
// skips characters until corresponding quote,
214+
// or end of file is reached
215+
while (fscanf(stdin, "%c", &curr_char) > 0) {
216+
if (curr_char == enclosing_char) break;
217+
}
218+
219+
// if corresponding quote was found, execution of TARGET search continues
220+
if (curr_char == enclosing_char) continue;
221+
222+
// otherwise, reached end of file without finding target
223+
else return 1;
224+
}
225+
226+
// clear space in buffer for new char
227+
for (size_t i = 0; i < (BUFFER_SIZE - 1); i++) {
228+
buffer[i] = buffer[i + 1];
229+
}
230+
231+
// forces character to lowercase if case insensitive is flagged
232+
if (case_insensitive) curr_char = tolower(curr_char);
233+
234+
// append next input char to buffer
235+
buffer[BUFFER_SIZE - 1] = curr_char;
236+
237+
// check if buffer contains TARGET
238+
if (strstr(buffer, target) != NULL) {
239+
// found TARGET
240+
return 0;
241+
}
242+
}
243+
244+
// reached end of file without finding TARGET
245+
return 1;
246+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#include "track.h"
2+
#include "trackpoint.h"
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <math.h>
7+
8+
char peak(FILE *in);
9+
void int_array2D_destroy(int **arr, int rows);
10+
11+
int main(int argc, char **argv)
12+
{
13+
double cell_width, cell_height;
14+
track *trk;
15+
int **map;
16+
int rows, cols;
17+
char* symbols;
18+
int symbol_range;
19+
int num_symbols;
20+
21+
cell_width = atof(argv[1]);
22+
cell_height = atof(argv[2]);
23+
symbols = argv[3];
24+
symbol_range = atoi(argv[4]);
25+
26+
// generate track with given trackpoint data
27+
trk = track_create();
28+
29+
char c;
30+
while ((c = peak(stdin)) != EOF)
31+
{
32+
double lat, lon;
33+
long time;
34+
trackpoint *pt;
35+
36+
// create new segement, if needed
37+
if (c == '\n')
38+
track_start_segment(trk);
39+
40+
fscanf(stdin, "%lf %lf %ld", &lat, &lon, &time);
41+
pt = trackpoint_create(lat, lon, time);
42+
track_add_point(trk, pt);
43+
44+
// clears '\n' at end of line
45+
fgetc(stdin);
46+
47+
trackpoint_destroy(pt);
48+
}
49+
50+
// track_print(trk);
51+
// printf("********************\n\n");
52+
53+
track_heatmap(trk, cell_width, cell_height, &map, &rows, &cols);
54+
55+
// testing
56+
// printf("%d, %d\n", rows, cols);
57+
58+
// for (int i = 0; i < rows; i++)
59+
// {
60+
// for (int j = 0; j < cols; j++)
61+
// {
62+
// printf("%d ", map[i][j]);
63+
// }
64+
// putchar('\n');
65+
// }
66+
67+
// printing heatmap
68+
num_symbols = strlen(symbols);
69+
70+
for (int i = 0; i < rows; i++)
71+
{
72+
for (int j = 0; j < cols; j++)
73+
{
74+
char symbol;
75+
int which_symbol;
76+
77+
which_symbol = fmin((map[i][j] / symbol_range), num_symbols - 1);
78+
symbol = symbols[which_symbol];
79+
80+
putchar(symbol);
81+
}
82+
putchar('\n');
83+
}
84+
85+
int_array2D_destroy(map, rows);
86+
track_destroy(trk);
87+
}
88+
89+
// peaks at next char in stream.
90+
// returns EOF if cannot read next char
91+
char peak(FILE *in)
92+
{
93+
char c = getc(in);
94+
return ungetc(c, in);
95+
}
96+
97+
// deallocates a 2d array
98+
void int_array2D_destroy(int **arr, int rows)
99+
{
100+
for (int i = 0; i < rows; i++)
101+
{
102+
free(arr[i]);
103+
}
104+
free(arr);
105+
}

0 commit comments

Comments
 (0)