diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 107 |
1 files changed, 107 insertions, 0 deletions
@@ -0,0 +1,107 @@ +//This program splits up questions and answers in a latex file and saves each to separate files. Questions are prefixed by "\section*{". Answers are prefixed by "\subsection*{" +#include <stdio.h>//basic I/O library +#include <stdlib.h>//library for malloc etc +#include <stdbool.h>//library for getting bools +#include <string.h>//We use this library just for strstr() + +#define DEFAULT_SIZE 100//the default size of the buffer is 100 bytes (100 chars) to balance peformace and memory usage. Realloc is also increased by this much each time + +int main(int argc, char *argv[]) +{ +if (!argv[1]){printf("No file given.\n"); return 1;}//return 1 if input isn't given + + +FILE *input = fopen(argv[1], "r");//file from where the question/answers are read +if (!input) +{ + printf("%s %s\n", "Error opening input file:", argv[1]); + return 1; +} + +FILE *questions = fopen("questions.tex", "a");//file where the questions are printed +if (!questions) +{ + printf("Error opening output file questions."); + return 1; +} + +FILE *answers = fopen("answers.tex", "a");//file where the answers are printed +if (!answers) +{ + printf("Error opening output file answers"); + return 1; +} + +unsigned short size = DEFAULT_SIZE;//set size int to the DEFAULT_SIZE value. (Only an int because you can't increase the value of static symbolic values. {Muh memory wasted}) +char *buffer = malloc(size*sizeof(char *));//malloc a 1D array of DEFAULT_SIZE length +if (!buffer){printf("Malloc failed!\n"); return 1;}//exit if malloc fails + +char c;//buffer char +bool question_or_answer = false;//When the current line needs to be written to the questions file; bool is false. When the current line needs to be written to the answers file; bool is true; +unsigned short i = 0;//i is used to count how many chars have been written to the buffer. +char *temp;//a pointer to a char. strstr() wants this, so we use it. + +c = fgetc(input);//read the first char in the file to c. +while(c != EOF)//exit if EOF is reached +{ +if (c != '\n')//if read char isn't a newline, add it to the buffer. + { + if (i==size)//check for when the buffer is about to become larger than the memory allocated. + { + size+=DEFAULT_SIZE;//size = size + DEFAULT_SIZE, to add an extra 100 chars every realloc + buffer = realloc(buffer, size);//realloc the buffer larger to fix those extra chars. + if (!buffer){printf("Realloc failed!\n"); return 1;}//If out of memory, exit + } + + buffer[i]=c; ++i; goto skip;//write char to buffer and skip ahead to next char reading + } + +if (c == '\n')//If the current char is newline, analyse the now made buffer for a question or answer marking and write that to the correct file +{ +buffer[i]=c;//Write newline to the buffer +temp = strstr(buffer, "\\section*");//If the current line is part of a question, "\section*" will be within it, and strstr will fine such + if (temp)//If temp isn't NULL, the string has been found + { + question_or_answer = false;//set the bool to question mode. + ++i; buffer[i] = '\0';//add a NULL terminator to the buffer so it can be printed. + fprintf(questions,"%s", buffer);//output to the questions file with fprintf + i = 0;//reset the buffer counter ready for a new read into the buffer + goto skip;//skip ahead to reading the next char + } +temp = strstr(buffer, "\\subsection*");//if the current line has "\\subsection*" in it, strstr will find as such. + if (temp)//If temp isn't NULL, the string has been found + { + question_or_answer = true;//Set the bool to answer writing mode + ++i; buffer[i] = '\0';//Add a NULL terminator to the buffer so it can be printed + fprintf(answers,"%s", buffer);//print the buffer to the answers file + i = 0;//reset the buffer counter + goto skip;//skip ahead to reading the next char + } + +switch(question_or_answer)//If above fell through, then the line in the buffer is not a section or subsection, but is still under a question or an answer. The correct file should be written to. + { + case 0://if question_or_answer is false, the last defermined output was a question + ++i; buffer[i] = '\0';//Add a NULL terminator so the buffer can be printed + fprintf(questions,"%s", buffer);//print the line to the questions file with fprintf + i = 0;//reset the buffer counter + break;//break so that the other case doesn't waste 1< CPU cycle checking for 1 + case 1://If question_or_answer is true, the last determined output was an answer + ++i; buffer[i] = '\0';///add a NULL terminator so that the line can be printed + fprintf(answers,"%s", buffer);//Use fprintf to write the line to the answers file + i = 0;//reset the buffer counter + //break; //yay, I saved a fraction of a CPU cycle by allowing a fall through instead of calling a break. (Or, I made it slower) + } + + +} + +skip: c = fgetc(input);//read the next char before looping up to the start of processing. If there's no more chars to read, then the while loop will determine EOF and will exit +} + +fclose(input);//close the input file +fclose(questions);//close the output file +fclose(answers);//close the output file +free(buffer);//free the malloce'd buffer + +return 0; +} |