0

I am trying to write a method that removes the first letter of a string and appends it to the end of the string with "ay" appended afterwards. I am using a linked list structure, and it works, but something is not 100% and I can't figure out why. It does what is't supposed to sometimes, but it seems to randomly add on parts of previous words. for example, the input "what the hell is wrong" should result as an output of "hatway hetay ellhay siay rongway", but it gives me "hatway hetwayay ellhayayay silhayayayay rongway"

Here is the piece that seems to have the bug:

typedef struct  wordNodeType
{
    char word[MAX_CHARS];
    struct wordNodeType *next;// pointer to next node
}WordNode;

struct wordNodeType *tempP;

WordNode* translateWord (WordNode* nextWord)
{
    strcpy(e,nextWord->word);
    strcpy(p, &e[strlen(e)-(strlen(e)-1)]);// remove first letter
    // remove newline char if there
    if(p[strlen(p)-1] == '\n')
        p[strlen(p)-1] = '\0';
    p[strlen(p)] = e[0];//move first char of e to last char of p ***the problem seems to happen here
    strcat(p,"ay");// append "tay" to end
    strcpy(tempP->word,p);
    return tempP;
}

I have memory allocated for the nodes, and the node does have a value in "word." The rest of my code works fine except for this minor bug that's driving me crazy! Any thoughts?

cHam
  • 2,624
  • 7
  • 26
  • 28
  • Also, I have validated that the calling function IS passing in a new node every time. – cHam Oct 31 '12 at 05:46
  • Where are `e` and `p` declared? – dreamlax Oct 31 '12 at 05:47
  • I also tried clearing the value "p" to NULL or " " after every loop but that didn't help either. – cHam Oct 31 '12 at 05:48
  • Why are they global? It seems the entire operation of converting a word to pig latin can be done without global variables. – dreamlax Oct 31 '12 at 05:49
  • I don't see why you shouldn't start it under debugger and see what happens with data on every line. Anyway, `p[strlen(p)] = e[0];` is incorrect - you breaking '\0' character and everything is falling apart. – keltar Oct 31 '12 at 05:58

2 Answers2

3

There is a little change that needs to be done to fix this. Here is the changed code:

WordNode* translateWord (WordNode* nextWord)
{
    strcpy(e,nextWord->word);
    strcpy(p, &e[strlen(e)-(strlen(e)-1)]);// remove first letter
    // remove newline char if there
    if(p[strlen(p)-1] == '\n')
        p[strlen(p)-1] = '\0';
int sizeofP = strlen(p);   /////Change Here
    p[strlen(p)] = e[0];//move first char of e to last char of p ***the problem seems to happen here
p[sizeofP + 1] = '\0';  /////Change Here
    strcat(p,"ay");// append "tay" to end
    strcpy(tempP->word,p);
    return tempP;
}

The problem was that when you wrote First character at the end of p, you overwrote the '\0' character and hence there was no way to reach the end of the string.

Aamir
  • 14,882
  • 6
  • 45
  • 69
  • Thank you, that took care of it. I would like to know though, I see how I was overwriting the '\0' char by just moving to the last element instead of +1, but what is the difference between using the strlen(p) and declaring an int = to strlen(p)? Just for my own knowledge moving forward. I know there is a lot I don't know, and it seems to me that they both have an int value so they should (wrongly as it seems) both yield similar results. – cHam Oct 31 '12 at 06:09
  • 1
    strlen takes some time to calculate length - it will count every char until it reach '\0'. So if you want to call it frequently - it could be better to calculate length once and save it somewhere. In addition, you can't call strlen after you just killed '\0', because it could return anything but not actual length. – keltar Oct 31 '12 at 06:16
  • Both points mentioned by @keltar are right however, in this case, second point is more relevant because it cannot calculate the length since there is no '\0'. The First point is more of an optimization thing. – Aamir Oct 31 '12 at 06:25
  • Good to know, and thank you both for the explanation and advice. – cHam Oct 31 '12 at 15:10
0

It seems to me that p and e are not getting cleared out all the way, and strcpy is just overwriting as many charcters into p as it needs. The algorithm that it uses in in the man pages, but essentially if the char-array p is not cleared and a shorter string is written in, the null-termination will not exist until after the length of the longest thing written in thus far. (this is why strlen is misleading you as well!)

If you don't fancy clearing p every time (Which you should) you may be able to fool the machine by just appending a,

char newChar = 0

after everytime you assign a value to p

darkpbj
  • 2,892
  • 4
  • 22
  • 32
  • Okay, I did clear "p" with p[0] = '\0'; (I can't believe I didn't try that before!) However, I still get the weird "(" added in the first word. "hatw(ay" any thoughts on that? – cHam Oct 31 '12 at 06:00
  • As a matter of fact I do--do what Aamir said! – darkpbj Oct 31 '12 at 06:04