misucik
misucik

Reputation: 21

Extra space added at the end of the last word

Here's my code. It's supposed to write down every second word, starting from START to STOP, from one file to another. The code works fine, but there is an extra space at the end of the last word. Any suggestions? I tried some things but ended up only with extra space in front, no spaces whatsoever, or multiple unwanted spaces.

#include <stdio.h>

#define MAX_BUFFER_SIZE 100

typedef struct {
    FILE *inputFile;
    FILE *outputFile;
} FilePair;

void initializeFiles(FilePair *files, char *inputFileName, char *outputFileName);
void closeFiles(FilePair *files);
void processFile(FilePair *files);

int main(int argc, char *argv[]) {
    FilePair files;

    initializeFiles(&files, argv[1], argv[2]);

    if (files.inputFile == NULL || files.outputFile == NULL) {
        return 1;
    }

    processFile(&files);

    closeFiles(&files);

    return 0;
}

void initializeFiles(FilePair *files, char *inputFileName, char *outputFileName) {
    files->inputFile = fopen(inputFileName, "r");
    files->outputFile = fopen(outputFileName, "w");

    if (files->inputFile == NULL || files->outputFile == NULL) {
        char error[] = "Error opening files\n";
        for (int i = 0; error[i] != '\0'; i++) {
            fputc(error[i], files->outputFile);
        }
        fclose(files->outputFile);
        files->outputFile = NULL; 
        fclose(files->inputFile);
        files->inputFile = NULL; 
        return;
    }
}

void closeFiles(FilePair *files) {
    if (files->inputFile != NULL) {
        fclose(files->inputFile);
        files->inputFile = NULL;
    }
    if (files->outputFile != NULL) {
        fclose(files->outputFile);
        files->outputFile = NULL;
    }
}

void processFile(FilePair *files) {
    char startMarker[7] = "START ";
    char stopMarker[5] = "STOP";
    char buffer[MAX_BUFFER_SIZE];
    int startIdx = 0, stopIdx = 0;
    int isStart = 0;
    int spaceCount = 0;

    while (1) {
        int character = fgetc(files->inputFile);
        if (character == EOF) {
            break;
        }

        for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
            buffer[i] = '\0';
        }

        buffer[0] = character;
        for (int i = 1; i < MAX_BUFFER_SIZE - 1; i++) {
            character = fgetc(files->inputFile);
            if (character == EOF || character == '\n') {
                break;
            }
            buffer[i] = character;
        }

        for (int i = 0; buffer[i] != '\0'; i++) {
            char ch = buffer[i];

            if (isStart) {
                if (spaceCount % 2 != 0) {
                    fputc(ch, files->outputFile);
                }
                if (ch == ' ') {
                    spaceCount++;
                }

                if (ch == stopMarker[stopIdx]) {
                    stopIdx++;
                } else {
                    stopIdx = 0;
                }
                if (stopMarker[stopIdx] == '\0') {
                    isStart = 0;
                }
            } else {
                if (ch == startMarker[startIdx]) {
                    startIdx++;
                } else {
                    startIdx = 0;
                }
                if (startMarker[startIdx] == '\0') {
                    isStart = 1;
                }
            }
        }
    }
}

I was only expecting to remove the space at the end of the last word

Upvotes: 2

Views: 99

Answers (1)

Neeraj Roy
Neeraj Roy

Reputation: 201

You can slightly modify your logic to remove the extra space at the end of the last word. One way to achieve this is to maintain a flag to check whether the current word is the last one.

Here's the modified code:

#include <stdio.h>

#define MAX_BUFFER_SIZE 100

typedef struct {
    FILE *inputFile;
    FILE *outputFile;
} FilePair;

void initializeFiles(FilePair *files, char *inputFileName, char *outputFileName);
void closeFiles(FilePair *files);
void processFile(FilePair *files);

int main(int argc, char *argv[]) {
    FilePair files;

    initializeFiles(&files, argv[1], argv[2]);

    if (files.inputFile == NULL || files.outputFile == NULL) {
        return 1;
    }

    processFile(&files);

    closeFiles(&files);

    return 0;
}

void initializeFiles(FilePair *files, char *inputFileName, char *outputFileName) {
    files->inputFile = fopen(inputFileName, "r");
    files->outputFile = fopen(outputFileName, "w");

    if (files->inputFile == NULL || files->outputFile == NULL) {
        char error[] = "Error opening files\n";
        for (int i = 0; error[i] != '\0'; i++) {
            fputc(error[i], files->outputFile);
        }
        fclose(files->outputFile);
        files->outputFile = NULL;
        fclose(files->inputFile);
        files->inputFile = NULL;
        return;
    }
}

void closeFiles(FilePair *files) {
    if (files->inputFile != NULL) {
        fclose(files->inputFile);
        files->inputFile = NULL;
    }
    if (files->outputFile != NULL) {
        fclose(files->outputFile);
        files->outputFile = NULL;
    }
}

void processFile(FilePair *files) {
    char startMarker[7] = "START ";
    char stopMarker[5] = "STOP";
    char buffer[MAX_BUFFER_SIZE];
    int startIdx = 0, stopIdx = 0;
    int isStart = 0;
    int spaceCount = 0;
    int lastWord = 0;

    while (1) {
        int character = fgetc(files->inputFile);
        if (character == EOF) {
            break;
        }

        for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
            buffer[i] = '\0';
        }

        buffer[0] = character;
        for (int i = 1; i < MAX_BUFFER_SIZE - 1; i++) {
            character = fgetc(files->inputFile);
            if (character == EOF || character == '\n') {
                lastWord = 1;  // Mark that this is the last word
                break;
            }
            buffer[i] = character;
        }

        for (int i = 0; buffer[i] != '\0'; i++) {
            char ch = buffer[i];

            if (isStart) {
                if (spaceCount % 2 != 0) {
                    fputc(ch, files->outputFile);
                }
                if (ch == ' ') {
                    spaceCount++;
                }

                if (ch == stopMarker[stopIdx]) {
                    stopIdx++;
                } else {
                    stopIdx = 0;
                }
                if (stopMarker[stopIdx] == '\0') {
                    isStart = 0;
                }
            } else {
                if (ch == startMarker[startIdx]) {
                    startIdx++;
                } else {
                    startIdx = 0;
                }
                if (startMarker[startIdx] == '\0') {
                    isStart = 1;
                }
            }
        }

        if (lastWord) {
            // Check if this is the last word and avoid adding an extra space
            fputc('\n', files->outputFile);
            break;
        }
    }
}

The lastWord variable is introduced to keep track of whether the current word is the last one. If it is the last word, it avoids adding an extra space at the end. Additionally, it adds a newline character to the output file to maintain a clean output. I hope this helps resolve your bug. For more assistance, you can comment below.

Upvotes: 1

Related Questions