0

I am working on a program that is in multiple parts that build off each other. The first program has to read from a file and write the content split up by spaces to a new file. Program two is supposed to take this words and add pig latin to them based on the rule of whether it starts with a vowel or a consonant and appending some string at the end depending on which it started with. I am able to open the file and read from the contents, but I am having trouble finding and appending the proper rules to print to the new file.

          int processingWord = 1; //0 is not in the middle of a word and 1 is in the middle
  char c;
  int bytes; //Should be holding the position of the pointer in the file
  while((bytes = read(fileRead, &c, sizeof(c))) > 0) {
    //printf("%c", c);
    if(processingWord == 0) {
      processingWord = 1;
    }
    if(processingWord == 1) {
      //Figure out if a vowel or not
      if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
        //Increment the first counter
        shard1Count++;
      }
      //Get to the end of the string
      if(c == '\n') {
        c = 'r';
        write(fileWrite, &c, sizeof(c));
        c = 'a';
        write(fileWrite, &c, sizeof(c));
        c = 'y';
        write(fileWrite, &c, sizeof(c));
        c = '\n';
        write(fileWrite, &c, sizeof(c));
        processingWord = 0;
      }
    }
    write(fileWrite, &c, sizeof(c));
  }

This is where I am trying to find and append the new "ray" string at the end of the word if it starts with a vowel. The text files look like this

It
is
the
Zucca
Gigantopithecus,
or
Great
Pumpkin,
Charlie
Brown.

And output is supposed to look like this in a new file

Itray 
    isray 
    hetay 
    uccaZay 
    igantopithecusGay, 
    orray
    reatGay
    umpkinPay, 
    harlieCay 
    rownBay.

EDIT: processsingWord was an idea I had to check if i was at the end of the line before I checked for vowels and what not. But the logic didn't workout and the output was all jibberish. My current output file looks like this:

Itray

isray

theray

Zuccaray

Gigantopithecus,ray

orray

Greatray

Pumpkin,ray

Charlieray

Brown.ray

ray
Sai Peri
  • 339
  • 1
  • 3
  • 17
  • Your comment says that `processingWord` should be 0 or 1, but in your program it is always 1. Did you mean to set it back to zero at some point? – Ben Voigt Oct 30 '18 at 01:04
  • Yeah so that was my initial logic. I had a if statement to first check if I wass at the end of the line before it checked for vowels etc. When I checked my temp2.data the output was all jibberish with a bunch of "?" marks. I accidentally deleted it for testing purposes. – Sai Peri Oct 30 '18 at 01:08
  • What is the current output, it looks like strcat isnt doing what you think it should be doing. either use a debugger or use sprintf, although if you use strcat it should work correctly. https://stackoverflow.com/questions/2674312/how-to-append-strings-using-sprintf Also initialize your BUFFER to 0 like this: char BUFFER[250] = {0}; – Bwebb Oct 30 '18 at 01:20
  • When I used the buffer my output was just random symbols as output. I have not gotten output to be like IIt, iis, thee etc.. so Im getting closer but I am not able to append the "ray" properly. I have updated my code above. – Sai Peri Oct 30 '18 at 01:21
  • Printf what the strlen is, i suspect your string isnt null terminated and so the strcat doesnt append correctly. Initializing to zero should help for the first write "itray" – Bwebb Oct 30 '18 at 01:23
  • I have decided to ditch the buffer method and try to do it character by character. I am not that experienced so I wouldn't have the time to try to debug it properly. – Sai Peri Oct 30 '18 at 01:26
  • well with the new implementation processingWord still doesnt do anything, after the \n is read and "ray\n" is appended/written, it sets it to 0 only to be set to 1 right after. What is the purpose of this flag? – Bwebb Oct 30 '18 at 01:28
  • For the second part of the pig latin part I have to take the first lettter of the word and then delete it and append to the end of the word. I initially was planning on using it for that but I haven't thought of the logic behind that yet. I do now get the proper output for the vowels though. I updated my code above – Sai Peri Oct 30 '18 at 01:33

1 Answers1

1

Here is an implementation that should work:

void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);


void doStuff(){
    int processingWord = 0; 
    int already_latin = 0;
    char c = 0;
    char first_letter = 0;
    while(read(fileRead, &c, sizeof(c)) > 0) {
        if(processingWord == 0) {
            processingWord = 1;
            if(!startsWithVowel(c)){ //append constants to the end of the word in pig latin *EDIT*
                first_letter = c;
                continue;//Here we do not fall through and write
            }
        }
        else{
            if(isALetter(c)){ //This is the general case of just writing the read character
                write(fileWrite, &c, sizeof(c));
            }
            else if(c != '\n'){ //Here is handling for , and . special characters
                if(isALetter(first_letter)){ //we hit a .  or , with a vower word, need to add first letter then "ray"
                    write(fileWrite, &first_letter, sizeof(first_letter));
                }
                write(fileWrite, "ray", sizeof("ray"));
                write(fileWrite, &c, sizeof(c));
                already_latin = 1;
            }
            else if(c == '\n') { //here is the end of the string
                if(isALetter(first_letter)){
                    write(fileWrite, &first_letter, sizeof(first_letter));
                }
                if(!already_latin){
                    write(fileWrite, "ray", sizeof("ray"));
                }
                write(fileWrite, &c, sizeof(c));

                processingWord = 0; //reset all the flags for the next word.
                first_letter = 0;
                already_latin = 0;
            }//end of '\n'
        }//end of if/else block
    }//end of while loop
}//end of function


/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */

int startsWithVowel(char c){
    if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
        return 1;
    }
    return 0;
}

/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
    if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
        return 1;
    }
    return 0;
}

There is still a bunch of unused stuff like the bytes variable, and things could certainly be cleaner, but this should work how you need it to. Try to run it and let me know how it goes, if im still here ill update any bugs tonight

EDIT Looks like i did it backwards, only swapping vowels (instead of constants). my pig Latin is rusty.

Ok I made a local string to test the parsing online with codechef.com/ide, you can copy and paste this in there to verify. Change the printfs to writes, which mimic the printfs and i think youre good to go:

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

void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);

char * str = "It\nis\nthe\nZucca\nGigantopithecus,\nor\nGreat\nPumpkin,\nCharlie\nBrown.";

int main(void) {

    doStuff();

    return 0;
}

void doStuff(){
    int processingWord = 0; 
    char c = 0;
    char first_letter = 0;
    int already_latin = 0;
    //while(read(fileRead, &c, sizeof(c)) > 0) {
    while(strlen(str) > 0){        //Made local for testing, no file io here
        c = str[0];
        str++;                    //end of local nonsense you wont have to use
        if(processingWord == 0) {
            processingWord = 1;
            if(!startsWithVowel(c)){
                first_letter = c;
                continue;//Here we don not fall through and write
            }
        }
        if(processingWord == 1) {
            if(isALetter(c)){ //This is the general case of just writing the read character
                //write(fileWrite, &c, sizeof(c));
                printf("%c",c);
                //printf(" SHOULD PRINT FIRST LETTER VOWEL HERE ");
            }
            else if(c != '\n'){ //Here is handling for , and . special characters
                if(isALetter(first_letter)){ //we hit a .  or , with a vower word, need to add first letter then "ray"
                    //write(fileWrite, &first_letter, sizeof(first_letter));
                    printf("%cay%c",first_letter,c);
                }
                else{
                    //write(fileWrite, "ray", sizeof("ray"));
                    //write(fileWrite, &c, sizeof(c));
                    printf("ray%c", c);   
                }
                already_latin = 1;
            }
            else if(c == '\n') { //here is the end of the string
                if(!already_latin){
                    if(isALetter(first_letter)){
                        //write(fileWrite, &first_letter, sizeof(first_letter));
                        printf("%cay",first_letter);
                        //printf(" SHOULD PRINT FIRST LETTER CONSTANT HERE  ");
                    }
                    else{
                        //write(fileWrite, "ray", sizeof("ray"));
                        printf("ray");
                    }
                }
                //write(fileWrite, &c, sizeof(c));
                printf("%c", c);
                processingWord = 0;
                first_letter = 0;
                already_latin = 0;
            }//end of '\n'
        }//end of if/else block
    }//end of while loop
}//end of function


/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */

int startsWithVowel(char c){
    if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
        return 1;
    }
    return 0;
}

/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
    if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
        return 1;
    }
    return 0;
}

OUTPUT: Itray isray hetay uccaZay igantopithecusGay, orray reatGay umpkinPay, harlieCay rownBay.

Bwebb
  • 675
  • 4
  • 14
  • Thanks for the response. I am actually in the process of making it work with my logic, although it is messy and long. Although I am able to follow your code relatively easy. Thank you so much for your answer, I will be trying it after I try my implementation. – Sai Peri Oct 30 '18 at 02:19
  • 1
    Some cleanup: If you move the `continue` outside its `if`, you can eliminate the outermost `else` that follows (i.e. less indentation). Likewise, you can add `continue` to `if`'s that follow at the same level. – Craig Estey Oct 30 '18 at 02:27
  • I use 2 space indents at work, these 4 space indents on codechef look huge to me lol. as long as it works ill let the OP do it however he wants, its his homework i assume. – Bwebb Oct 30 '18 at 02:41
  • @SaiPeri if you end up using this working sample code can you accept this comment as a answer to your question. – Bwebb Oct 30 '18 at 02:43
  • I ended up getting my implemention for fear of getting caught for academic dishonesty but for our second part we have to utilize threads so I will definitely look at your implementation to make my life easier when we get our next assignment. Thank you very much – Sai Peri Oct 31 '18 at 03:13