Created
January 1, 2022 19:51
-
-
Save weirddan455/638b478d2eacfd3659396bf99962daa0 to your computer and use it in GitHub Desktop.
Advent of Code Input Parsing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
int main(void) | |
{ | |
// Using POSIX open/read functions | |
// If using Windows, you probably want to use fopen/fread (or native Windows API) | |
// From my testing, these functions don't work very well on Windows. | |
// PS: The process of opening/reading the file can be copy+pasted and used in every AoC puzzle (works the same for any input). | |
// Open the file. open() returns a file descriptor "fd" that refers to the file. | |
int fd = open("input", O_RDONLY); | |
if (fd == -1) | |
{ | |
perror("open"); | |
return 1; | |
} | |
// Get the file size using fstat (fileInfo struct in an output parameter) | |
struct stat fileInfo; | |
if (fstat(fd, &fileInfo) != 0) | |
{ | |
perror("fstat"); | |
close(fd); | |
return 1; | |
} | |
// Allocate memory equal to the file size. | |
char *data = malloc(fileInfo.st_size); | |
if (data == NULL) | |
{ | |
puts("malloc failed"); | |
close(fd); | |
return 1; | |
} | |
// Read the contents of the file into the buffer we just allocated. | |
ssize_t bytesRead = read(fd, data, fileInfo.st_size); | |
// Close the file. It's read into the buffer and we don't need it anymore. | |
close(fd); | |
// -1 return value means failure. In this case, it will put the error number into "errno" which we can print out with perror() to understand why it failed. | |
if (bytesRead == -1) | |
{ | |
perror("read"); | |
free(data); | |
return 1; | |
} | |
// Check that we actually read in the entire file. | |
if (bytesRead != fileInfo.st_size) | |
{ | |
printf("Error: read %d bytes. %d expected.\n", bytesRead, fileInfo.st_size); | |
free(data); | |
return 1; | |
} | |
// Count up the newlines in the input. This gives us the number of entries. In day 1, they're all just ints. | |
int numbers = 0; | |
for (ssize_t i = 0; i < bytesRead; i++) | |
{ | |
if (data[i] == '\n') | |
{ | |
numbers++; | |
} | |
} | |
// Allocate memory to store the ints we're about to parse. | |
int *array = malloc(numbers * sizeof(int)); | |
if (array == NULL) | |
{ | |
puts("malloc failed"); | |
free(data); | |
return 1; | |
} | |
// Actual parsing begins. | |
ssize_t dataIndex = 0; | |
// Loop for each number in the input. | |
for (int i = 0; i < numbers; i++) | |
{ | |
// Declare a string on the stack and keep track of its index. | |
// String needs to be large enough to hold each digit + a null termination character. | |
int stringIndex = 0; | |
char string[8]; | |
// Continue until we hit a newline. If on Windows, this may need to be replaced by '\r' if you have CRLF line endings. | |
while (data[dataIndex] != '\n') | |
{ | |
// Copy each digit into the string, advancing both indicies afterwards. | |
string[stringIndex++] = data[dataIndex++]; | |
} | |
// Advance the dataIndex one more time to skip past the newline. If CRLF, do dataIndex += 2; instead. | |
dataIndex++; | |
// Add in the null termination character. | |
string[stringIndex] = 0; | |
// Use the atoi function to convert the string of digits into an int and store that value into our array. | |
array[i] = atoi(string); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment