Скачиваний:
2
Добавлен:
25.01.2023
Размер:
8.97 Кб
Скачать
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLEN 256

#if defined(_WIN32) || defined(WIN32) || defined(WINNT) || defined(MSVC)
    #define clear_console() system("cls")
#else
    #define clear_console() system("clear")
#endif

/* Arguments: buffer - allocated buffer of chars,
 *            size - size of the buffer,
 *            last_str - the string to stop input.
 * Return value: size of data in the buffer.
 * Purpose: reads lines from the console to the given buffer,
 *          until the user enters the specified string. */
size_t read_from_console(char *buffer, size_t size, char *last_str);

/* Arguments: buffer - allocated buffer of chars,
 *            size - size of the buffer,
 *            file - handle of the file, opened for reading.
 * Return value: size of data in the buffer.
 * Purpose: reads a text (data without zeros) to the given buffer from the file. */
size_t read_from_file(char *buffer, size_t size, FILE* file);

/* Arguments: n - length of the line,
 *            c - char for printing.
 * Purpose: prints a line of given chars to the console. */
void print_line_of_chars(size_t n, char c);

/* Arguments: buffer - pointer to the string.
 * Purpose: prints text to the console and underlines comments. */
void print_analysis(char *buffer);

/* Arguments: buffer - pointer to the string,
 *            file - handle of the file, opened for writing.
 * Purpose: writes text to the file, replacing cpp-like comments. */
void write_result(char *buffer, FILE *file);

int main() {
    size_t size;
    char *text;
    char input_str[MAXLEN],
         output_str[MAXLEN];
    FILE *input, *output;
    
    /* Main cycle of the program */
    do {
        output = NULL;
        input = NULL;

        clear_console();
        puts(",---------------------------------------,");
        puts("|       C++ to C comment replacer       |");
        printf("|    Max line size: % 10d bytes    |\n", (int)(MAXLEN - 1));
        printf("|    Max text size: % 10d bytes    |\n", (int)(MAXLEN * MAXLEN - 1));
        puts("'---------------------------------------'\n");
        
        puts("Source: file or console? Default: console");
        fgets(input_str, MAXLEN, stdin);
        input_str[strlen(input_str) - 1] = '\0';
        if (input_str[0] == '\0' || strcmp(input_str, "console") == 0) {
            strncpy(input_str, "console", MAXLEN);
            input = stdin;
        } else if (strcmp(input_str, "file") == 0) {
            puts("Enter a name of the file:");
            fgets(input_str, MAXLEN, stdin);
            input_str[strlen(input_str) - 1] = '\0';

            if ((input = fopen(input_str, "r")) == NULL)
                printf("File \"%s\" does not exist or cannot be readed!\n", input_str);
        } else
            printf("\"%s\": unknown source type!\n", input_str);

        if (input != NULL) {
            puts("Destination: file or console? Default: console");
            fgets(output_str, MAXLEN, stdin);
            output_str[strlen(output_str) - 1] = '\0';
            if (output_str[0] == '\0' || strcmp(output_str, "console") == 0) {
                strncpy(output_str, "console", MAXLEN);
                output = stdout;
            } else if (strcmp(output_str, "file") == 0) {
                puts("Enter a name of the file:");
                fgets(output_str, MAXLEN, stdin);
                output_str[strlen(output_str) - 1] = '\0';

                if ((output = fopen(output_str, "w")) == NULL)
                    printf("File \"%s\" cannot be created or used for writing!\n", output_str);
            } else
                printf("\"%s\": unknown destination type!\n", output_str);

            if (output != NULL) {
                clear_console();
                size = MAXLEN * MAXLEN;
                text = (char *)malloc(size);

                if (text != NULL) {
                    if (input == stdin) {
                        puts("Enter the text and type string \"\\q\" to continue:");
                        size = read_from_console(text, size, "\\q\n");
                        clear_console();
                    } else
                        size = read_from_file(text, size, input);

                    if (size > 0) {
                        text = (char *)realloc(text, size);
                        printf("Input: %s\n", input_str);
                        printf("Output: %s\n", output_str);
                        puts("Analysis (\"~\" - comments for replacement):\n");
                        print_analysis(text);
                        puts("\nEnter any key to continue...");
                        getchar();
                        clear_console();
                        puts("Writing result...\n");
                        write_result(text, output);
                        puts("\nSuccess!");
                    } else
                        printf("Warning: zero-sized buffer, please check its initial size\n");
                    free(text);
                    text = NULL;
                } else
                    puts("Memory allocation error!");

                if (output != stdout)
                    fclose(output);
            }
            if (input != stdin)
                fclose(input);
        }
        puts("Try again? (y/n)");
        fgets(input_str, MAXLEN, stdin);
    } while (input_str[0] == 'y' || input_str[0] == 'Y' || input_str[0] == '\n');
    return 0;
}

size_t read_from_console(char *buffer, size_t size, char *last_str) {
    char *c;
    char temp[MAXLEN];
    size_t res_size;
    res_size = 0;
    if (size > 0) {
        while (res_size < size && strcmp(fgets(temp, MAXLEN, stdin), last_str)) {
            for(c = temp; *c && res_size < size; res_size++, c++)
                buffer[res_size] = *c;
        }
        if (res_size == size)
            buffer[size - 1] = '\0';
        else
            buffer[res_size++] = '\0';
    }
    return res_size;
}

size_t read_from_file(char *buffer, size_t size, FILE* file) {
    size_t res_size;
    res_size = 0;
    if (size > 0) {
        res_size = strnlen(buffer, fread(buffer, 1, size, file));
        if (res_size == size)
            buffer[size - 1] = '\0';
        else
            buffer[res_size++] = '\0';
    }
    return res_size;
}

void print_line_of_chars(size_t n, char c) {
    size_t i;
    for (i = 0; i < n; i++)
        putchar(c);
}

void print_analysis(char *buffer) {
    char last_c, is_cpp_style, is_c_style, is_string;
    char *c, *line_start, *comment_start;
    is_cpp_style = 0;
    is_c_style = 0;
    is_string = 0;
    last_c = 0;
    for (line_start = c = buffer; *c; c++) {
        if (*c == '\n') {
            if (is_cpp_style) {
                is_cpp_style = 0;
                putchar('\n');
                print_line_of_chars(comment_start - line_start, ' ');
                print_line_of_chars(c - comment_start, '~');
            }
            line_start = c + 1;
        } else if (is_c_style) {
            if (last_c == '*' && *c == '/')
                is_c_style = 0;
        } else if (!is_cpp_style) {
            if (*c == '\"')
                is_string = 1 - is_string;
            else if (!is_string && last_c == '/') {
                if (*c == '/') {
                    is_cpp_style = 1;
                    comment_start = c;
                } else if (*c == '*')
                    is_c_style = 1;
            }
        }
        putchar(*c);
        last_c = *c;
    }
    if (is_cpp_style) {
        putchar('\n');
        print_line_of_chars(comment_start - line_start, ' ');
        print_line_of_chars(c - comment_start, '~');
    }
}

void write_result(char *buffer, FILE *file) {
    char last_c, is_cpp_style, is_c_style, is_string, need_to_print;
    char *c;
    is_cpp_style = 0;
    is_c_style = 0;
    is_string = 0;
    last_c = 0;
    for (c = buffer; *c; c++) {
        need_to_print = 1;
        if (is_c_style) {
            if (last_c == '*' && *c == '/')
                is_c_style = 0;
        } else if (is_cpp_style) {
            if (*c == '\n') {
                need_to_print = 0;
                is_cpp_style = 0;
                fputs(" */\n", file);
            }
        } else {
            if (*c == '\"')
                is_string = 1 - is_string;
            else if (!is_string && last_c == '/') {
                if (*c == '/') {
                    is_cpp_style = 1;
                    need_to_print = 0;
                    fputc('*', file);
                } else if (*c == '*')
                    is_c_style = 1;
            }
        }
        if (need_to_print)
            fputc(*c, file);
        last_c = *c;
    }
    if (is_cpp_style)
        fputs(" */", file);
}
Соседние файлы в папке Курсовая про замену комментариев