Reputation: 21
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
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