186 lines
3.6 KiB
C
186 lines
3.6 KiB
C
/* License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
|
*
|
|
* Exercise 1 - Implementing a Stack (Week 2)
|
|
* Name: Manish
|
|
* Student Login: *****
|
|
*
|
|
* Compile as:
|
|
* $ gcc -std=c11 -Wall -o ex1 ex1.c
|
|
*/
|
|
|
|
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
// 20 character + 1 for null-terminating character '\0'
|
|
char stack[1000][21];
|
|
const size_t stack_size = 1000;
|
|
const size_t word_len = 20;
|
|
size_t stack_index = 0; // index pointer to 0 implies empty
|
|
|
|
|
|
void push(char * string);
|
|
char* pop();
|
|
char* top();
|
|
bool isEmpty();
|
|
void input_line(char* string[], size_t *size);
|
|
void readline(FILE* file, char* string[], size_t *size);
|
|
// void input_word(char* string[], size_t *size);
|
|
// void readword(FILE* file, char* string[], size_t *size);
|
|
void baseread(
|
|
FILE* file,
|
|
char* string[],
|
|
size_t *size,
|
|
const char * terminating_characters);
|
|
|
|
|
|
int main (void)
|
|
{
|
|
printf("Enter file name: ");
|
|
char* filename;
|
|
size_t filename_len = 0;
|
|
input_line(&filename, &filename_len);
|
|
|
|
FILE* file = fopen(filename, "r");
|
|
if (!file)
|
|
{
|
|
perror(filename);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Read and push words to stack
|
|
char word[word_len+1];
|
|
size_t index;
|
|
char c;
|
|
while(!feof(file) && !ferror(file))
|
|
{
|
|
index = 0;
|
|
while(
|
|
(c = fgetc(file)) != EOF
|
|
&& !ferror(file)
|
|
&& memchr("\n\r ", c, 4) == NULL)
|
|
{
|
|
if (index < word_len)
|
|
{
|
|
word[index++] = c;
|
|
}
|
|
}
|
|
word[index] = '\0';
|
|
|
|
if (index > 0) // non-empty string
|
|
{
|
|
push(word);
|
|
}
|
|
}
|
|
|
|
fclose(file);
|
|
|
|
// Print and pop words from stack
|
|
while(!isEmpty())
|
|
{
|
|
printf("%s ", pop());
|
|
}
|
|
printf("\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void push(char * string)
|
|
{
|
|
if (stack_index < stack_size)
|
|
{
|
|
strcpy(stack[stack_index++], string);
|
|
}
|
|
}
|
|
|
|
|
|
char* pop()
|
|
{
|
|
if (!isEmpty())
|
|
{
|
|
return stack[--stack_index];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
char* top()
|
|
{
|
|
if (!isEmpty())
|
|
{
|
|
return stack[stack_index-1];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
bool isEmpty()
|
|
{
|
|
return stack_index <= 0;
|
|
}
|
|
|
|
|
|
inline void input_line(char* string[], size_t *size)
|
|
{
|
|
readline(stdin, string, size);
|
|
}
|
|
|
|
|
|
inline void readline(FILE* file, char* string[], size_t *size)
|
|
{
|
|
baseread(file, string, size, "\n\r");
|
|
}
|
|
|
|
|
|
// inline void input_word(char* string[], size_t *size)
|
|
// {
|
|
// readword(stdin, string, size);
|
|
// }
|
|
|
|
|
|
// inline void readword(FILE* file, char* string[], size_t *size)
|
|
// {
|
|
// baseread(file, string, size, "\n\r ");
|
|
// }
|
|
|
|
|
|
// Used only for receiving filename
|
|
void baseread(
|
|
FILE* file,
|
|
char* string[],
|
|
size_t *size,
|
|
const char * terminating_characters)
|
|
{
|
|
size_t term_chars_len = strlen(terminating_characters);
|
|
size[0] = 32;
|
|
*string = malloc(size[0]);
|
|
// 1 reserved for null-terminating character '\0'
|
|
size_t memory_free = *size - 1;
|
|
size_t str_index = 0;
|
|
char c;
|
|
while ((c = fgetc(file)) != EOF
|
|
&& !ferror(file)
|
|
&& memchr(terminating_characters, c, term_chars_len) == NULL)
|
|
{
|
|
if (--memory_free <= 0)
|
|
{
|
|
memory_free = *size;
|
|
*size *= 2;
|
|
*string = realloc(*string, *size);
|
|
if (!*string)
|
|
{
|
|
perror("ERROR: Not enough memory to read entire stdin");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
string[0][str_index++] = c;
|
|
}
|
|
string[0][str_index++] = '\0';
|
|
*size = str_index;
|
|
*string = realloc(*string, *size); // free extra memory
|
|
}
|