Aglek
Aglek

Reputation: 11

Printing binary tree to file provided by the user

I'm writing a program that's supposed to take a text from a file and put all the words in alphabetical order, and also write next to each word in which lines it occurred. I'm having a problem with printing everything to another file. I have it printing the results into console, but don't know how to get it to the file. Could anyone help? Here's my code

#include <stdio.h>
#include <stdlib.h>
#include "string.h"

void help() {
    printf("This program counts symbols and words in each line. \n"
           " You have to write a name of the program, -i and input name, \n"
           " and -o and output name, remember to put .txt after \n"
           " input and output name and .exe after program name. \n "); // TODO
}

int CommandConsole(int argc, char *argv[], char limiter[]) {
    int i;

    for (i = 1; i < argc; i++) {
        if (argv[i][0] == limiter[0] && argv[i][1] == limiter[1]) { //strcmp
            break;
        }
    }
    return i + 1;
}

typedef struct lineNode {
    int line;
    struct lineNode *right;
} lineNode_t;

typedef struct node {
    char *word;
    lineNode_t *lineNodeHead;
    struct node *left, *right;
} node_t;

lineNode_t *insertLineCount(lineNode_t *line, int lineCount) {
    if (line == NULL) {
        if ((line = (lineNode_t *)malloc(sizeof(lineNode_t))) != NULL) {
            line->right = NULL;
            line->line = lineCount;
        }
    } else {
        line->right = insertLineCount(line->right, lineCount);
    }
    return line;
}

node_t *inserttree(node_t *tree, char *currentWord, int lineCount) {
    if (tree == NULL) {
        if ((tree = (struct node *)malloc(sizeof(struct node))) != NULL) {
            tree->left = NULL;
            tree->right = NULL;
            strcpy(tree->word, currentWord);
            tree->lineNodeHead = insertLineCount(NULL, lineCount);
        }
    } else
    if (strcmp(tree->word, currentWord) > 0) {
        tree->left = inserttree(tree->left, currentWord, lineCount);
    } else
    if (strcmp(tree->word, currentWord) < 0) {
        tree->right = inserttree(tree->right, currentWord, lineCount);
    } else {
        tree->lineNodeHead = insertLineCount(tree->lineNodeHead, lineCount);
    }

    return tree;
}

void freetree(struct node *tree) {
    if (tree != NULL) {
        free(tree->word);
        freetree(tree->left);
        freetree(tree->right);
        free(tree);
    }
}

void printLineCount(lineNode_t *line, FILE *fileout) {
    while (line != NULL) {
        printf("%d, ", line->line);
        line = line->right;
    }
    printf("\n\n");
}

void printtree(struct node *tree, FILE *fileout) {
    if (tree != NULL) {
        printtree(tree->left, fileout);
        printf("%s found in:\n", tree->word);
        printLineCount(tree->lineNodeHead, fileout);
        printtree(tree->right, fileout);
    }
}

void freeTreeLine(struct node *tree) {
    while (tree->lineNodeHead != NULL) {
        struct node *aux = tree->lineNodeHead;
        tree->lineNodeHead = tree->lineNodeHead->right;
        free(aux);
    }
}

void freeTree(struct node *tree) {
    if (tree->left != NULL) {
        freetree(tree->left);
    }
    if (tree->right != NULL) {
        freetree(tree->right);
    }
    freeTreeLine(tree);
    free(tree->word);
    free(tree);
}

int main(int argc, char *argv[]) {
    struct node *tree = NULL;
    int letter = '\0';
    char word[100];
    int i = 0;
    int lineCount = 0;

    if (argc == 5) {
        FILE *filein = fopen(argv[CommandConsole(argc, argv, "-i")], "r");
        FILE *fileout = fopen(argv[CommandConsole(argc, argv, "-o")], "w");
        if (filein != NULL) {
            while ((letter = fgetc(filein)) != EOF && i < 99) {
                if (isalnum(letter) == 1 || letter == 39) {
                    word[i] = letter;
                    word[++i] = '\0';
                } else {
                    if (letter == '\n') {// new line
                        lineCount++;
                    }
                    tree = inserttree(tree, word, lineCount);
                    for (int j = 0; j < i; j++) {
                        //fputc(word[j], fileout);
                        word[j] = ' ';
                    }
                    i = 0;
                }
            }
            //            printtree(tree,fileout);
            fclose(filein);
            fclose(fileout);
        } else {
            printf("File error!\n");
        }
    } else {
        help();
    }
    return 0;
}

Upvotes: -1

Views: 73

Answers (2)

Aglek
Aglek

Reputation: 11

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"

void help()
{
    printf("This program shows You words in alphabetical order as well as in which lines they occur. \n You have to write a name of the program, -i and input name, \n and -o and output name, remember to put .txt after \n input and output name and .exe after program name. \n ");
}
int CommandConsole(int argc, char *argv[], char limiter[])
{
    int i;
    for (i = 1; i < argc; i++) {
        if (argv[i][0] == limiter[0] && argv[i][1] == limiter[1])
        {
            break;
        }
    }
    return i + 1;
}

typedef struct lineNode
{
    int line;
    struct lineNode *right;
}lineNode_t;

typedef struct node
{
    char *word;
    lineNode_t *lineNodeHead;
    struct node *left, *right;
}node_t;

lineNode_t *insertLineCount(lineNode_t *line, int lineCount) {
    if (line != NULL) {
        if (line->right == NULL)
        {
            line->right = (lineNode_t *)malloc(sizeof(lineNode_t));
            line->right->right = NULL;
            line->right->line = lineCount;
        }
        else {
            line->right = insertLineCount(line->right, lineCount);
        }
    }
    else {
        line = (lineNode_t *)malloc(sizeof(lineNode_t));
        line->right = NULL;
        line->line = lineCount;
    }
    return line;
}

node_t *inserttree(node_t *tree, char *currentWord, int lineCount)
{
    if (tree == NULL)
    {
        tree = (struct node *) malloc(sizeof(struct node));
        tree->left = NULL;
        tree->right = NULL;
        tree->word = malloc(sizeof(char)*(strlen(currentWord) + 1));
        strcpy(tree->word, currentWord);
        tree->lineNodeHead = insertLineCount(NULL, lineCount);
    }
    else if (strcmp(tree->word, currentWord) > 0) {
        tree->left = inserttree(tree->left, currentWord, lineCount);
    }
    else if (strcmp(tree->word, currentWord) < 0) {
        tree->right = inserttree(tree->right, currentWord, lineCount);
    }
    else {
        tree->lineNodeHead = insertLineCount(tree->lineNodeHead, lineCount);
    }
    return tree;
}

void printLineCount(lineNode_t *line, FILE *fileout) {
    while (line != NULL) {
        fprintf(fileout, "%d, ", line->line);
        line = line->right;
    }
    fprintf(fileout, "\n\n");
}

void printtree(struct node *tree, FILE *fileout)
{
    if (tree != NULL)
    {
        printtree(tree->left, fileout);
        fprintf(fileout, "%s found in:\n", tree->word);
        printLineCount(tree->lineNodeHead, fileout);
        printtree(tree->right, fileout);
    }
}

void freeTreeLine(struct node *tree) {
    while (tree->lineNodeHead != NULL) {
        lineNode_t *aux = tree->lineNodeHead;
        tree->lineNodeHead = tree->lineNodeHead->right;
        free(aux);
    }
}

void freeTree(struct node *tree)
{
    if (tree->left != NULL) {
        freeTree(tree->left);
    }
    if (tree->right != NULL) {
        freeTree(tree->right);
    }
    freeTreeLine(tree);
    free(tree->word);
    free(tree);
}

int main(int argc, char * argv[]) {
    struct node *tree = NULL;
    char letter = '\0';
    char word[100];
    int i = 0;
    int lineCount = 1;
    if (argc == 5) {
        FILE *filein = fopen(argv[CommandConsole(argc, argv, "-i")], "r");
        FILE *fileout = fopen(argv[CommandConsole(argc, argv, "-o")], "w");
        if (filein != NULL) {
            while ((letter = fgetc(filein)) != EOF && i < 99)
            {
                if (letter > 0 && letter < 256) {
                    if (isalnum(letter) != 0) {
                        word[i] = letter;
                        word[++i] = '\0';
                    }
                    else {
                        if (letter == '\n') {
                            lineCount++;
                        }
                        tree = inserttree(tree, word, lineCount);
                        i = 0;
                    }
                }
            }
            if (tree != NULL) {
                if (fileout != NULL)
                    printtree(tree, fileout);

                freeTree(tree);
            }
            fclose(filein);
            fclose(fileout);
        }
        else {
            printf("File error!\n");
        }
    }
    else
    {
        help();
    }
    return 0;
}

Upvotes: 0

chqrlie
chqrlie

Reputation: 145277

Instead of using printf, you should use fprintf in the tree printing functions:

void printLineCount(lineNode_t *line, FILE *fileout) {
    while (line != NULL) {
        fprintf(fileout, "%d, ", line->line);
        line = line->right;
    }
    fprintf(fileout, "\n\n");
}

void printtree(struct node *tree, FILE *fileout) {
    if (tree != NULL) {
        printtree(tree->left, fileout);
        fprintf(fileout, "%s found in:\n", tree->word);
        printLineCount(tree->lineNodeHead, fileout);
        printtree(tree->right, fileout);
    }
}

Furthermore, fprintf(fileout, "%s found in:\n", tree->word); should only be executed if tree->lineNodeHead is NULL.

Also note this:

  • isalnum(letter) == 1 is incorrect. isalnum() and the other character class functions in <ctype.h> return 0 if the argument is not a letter or digit, and non-zero if it is. Do not compare == 1, just write isalnum(letter).

  • you have 2 functions: freeTree() that frees the line numbers and freetree() that does not. And the former calls the latter. This is incorrect as line numbers will not be freed below the first level.

  • do not hardcode ASCII values such as 39, use character constant '\'' instead.

Upvotes: 0

Related Questions