diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a4dbfc..fba36ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.0) project(learningc LANGUAGES C) set(CHAPTER 1) -set(EXERCISE 22) +set(EXERCISE 23) add_executable(learningc chapters/${CHAPTER}/exercises/${EXERCISE}.c) diff --git a/chapters/1/exercises/23.c b/chapters/1/exercises/23.c new file mode 100644 index 0000000..b8cbb65 --- /dev/null +++ b/chapters/1/exercises/23.c @@ -0,0 +1,11 @@ +#include +#include "shared/functions.h" +#include "shared/functions/uncomment.c" + +int main() { + char line[MAXLINE]; + while (uncomment(line,MAXLINE) != EOF) { + printf("%s", line); + } + return 0; +} diff --git a/chapters/1/exercises/shared/functions.h b/chapters/1/exercises/shared/functions.h index 498798b..6abc644 100644 --- a/chapters/1/exercises/shared/functions.h +++ b/chapters/1/exercises/shared/functions.h @@ -7,3 +7,4 @@ int getlines(char line[], int maxline); int detab(char s[],int lim, int col); int entab(char s[], int lim, int col); int fold(char s[], int lim, int cpr); +int uncomment(char s[],int lim); diff --git a/chapters/1/exercises/shared/functions/uncomment.c b/chapters/1/exercises/shared/functions/uncomment.c new file mode 100644 index 0000000..bd425d4 --- /dev/null +++ b/chapters/1/exercises/shared/functions/uncomment.c @@ -0,0 +1,58 @@ +#include + +int com = 0; + +/* + * TODO: + * Keep backbuffer of 1 character (current & i-1) to check for comment ends + * Handle double slashes nicely + * Find a cleaner way to achieve this +*/ + +int uncomment(char s[],int lim) { + int c, i, quo = 0, wnl = 0; + /* c is character integer + * i is column + * com is current comment state + * quo is current quote state */ + for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) { + /* Check if we are in a character constant or between quotes, if yes ignore comments */ + if (c == '"' || (c == '\'' && s[i-1] != '"')) { + if (quo == 1) { + quo = 0; //test + } else { + quo = 1; + } + } else if (quo == 0 && (c == '/' || c == '*')) { + if (com == 0) { + if (c == '*' && s[i-1] == '/') { + com = 1; + } else if (c == '/' && s[i-1] == '/') { + wnl = 1; + s[i-1] = ' '; + } + } else if (com == 1 && c == '/' && s[i-1] == '*') { + com = 0; + } + } + if (com == 0 && wnl == 0) { + s[i] = c; + } else { + s[i] = ' '; + } + } + /* If the line is completly empty, do not print a new line, jump to the next line */ + for (;i > 0 && (s[i-1] == ' ' || s[i-1] == '\t'); i--); + if (i == 0) { + s[i] = '\0'; + } else { + s[i] = '\n'; + s[i+1] = '\0'; + } + /* If we have hit the end of the line, tell the previous function, else return the lenght */ + if (c == EOF) { + return EOF; + } else { + return i; + } +}