0

I already asked this question in combination with another question, but I thought those are irrelevant to each other and honestly only one was getting answered, so I created a separate question thread to maximize my chances of solving this and to stop plugging my hair out.

So, The Asked problem is simple : print only unique words from a sentence (in order). Now I already brewed up my code Used strtok() to split up the string and it works just fine but the problem shows its head when I try to separate the said code to a function, it suddenly fails one test case. Let me show you what I mean :


The Code in question, inlined to the main method itself

int exists(char words[][MAX], int n, char *word){
    for(int i=0;i < n;i++)
        if(strcmp(words[i],word) == 0) 
            return 1;
    return 0;
}

int main(){
    char sentence[MAX*50] = {0}; //arbitary length
    fgets(sentence,MAX*50,stdin);

    //Solution to the Said Problem
    char words[10][MAX] = {0};
    int wi=0;
    
    for(char* tok=sentence;(tok=strtok(tok," \n"))!=NULL;tok=NULL)
        if(exists(words,wi,tok)==0)
            strcpy(words[wi++],tok);

    for(int i=0;i<wi;i++) printf("%s ",words[i]);
}

Results, Inlined


The Code in question, separated as a Function

int exists(char words[][MAX], int n, char *word){
    for(int i=0;i < n;i++)
        if(strcmp(words[i],word) == 0) 
            return 1;
    return 0;
}

void purgeDuplicates(char* sentence){//The code with not even a change to its whitespaces
    char words[10][MAX] = {0};
    int wi=0;
    
    for(char* tok=sentence;(tok=strtok(tok," \n"))!=NULL;tok=NULL)
        if(exists(words,wi,tok)==0)
            strcpy(words[wi++],tok);

    for(int i=0;i<wi;i++) printf("%s ",words[i]);
}

int main(){
    char sentence[MAX*50] = {0}; //arbitary length
    fgets(sentence,MAX*50,stdin);
    
    purgeDuplicates(sentence);
}

Results, In Function


The Output Of the Program(for both) is :

Input :

ab cd gh ef ab ab gh cd

Output :

ab cd gh ef


Now what I tried :

  • Changed function parameter datatype signature for sentence to char**, and passed the address of the first index of the sentence [By copying it to a pointer first](Might have screwed it up).
  • Copied the whole array to a new character array and passed it to function [Same Results].
  • Copied the whole array to a new character array inside function [same story].
  • Changed to accept parameter as Array instead of pointer[Same Story].
  • Debugged the program but couldn't get any viable information regarding the problem, but what I gathered is strtok() modifies the original string by placing '\0' on areas where delimiters are present in string. But it is doing it on both scenarios and linked list implementation of the solution uses strtok in its function (and it is changing the original string as previously said) yet it produces correct results.

Note : All methods are executed in separate instances and not back to back

ARG
  • 1
  • 3
  • 1
    You're probably writing past the end of your array. Rather than blindly assuming everything is fine, add a check to confirm that you never have more than 10 words. If you do, give an error. – Tom Karzes Oct 04 '22 at 08:25
  • `char words[10][MAX] = {0};` never gets filled with meaningful data before calling `exists`. And since `exists` must return true for meaningful data to be copied, nothing works. Spending a few minutes in a debugger ought to have revealed this, yeah? – Lundin Oct 04 '22 at 10:28
  • @Lundin Hi Lundin, actually the exists must return false for the data to be copied as I only allow the words to be copied if it didn't exist in the array before. – ARG Oct 05 '22 at 06:23
  • @TomKarzes Hi Tom, thank you it was indeed the problem, but why didn't it given me trouble when it was in main function? – ARG Oct 05 '22 at 06:25
  • @ARG Because it was in a different location on the stack, with other variables in different relative positions. It was corrupting memory in both cases. It just manifested itself differently. That's how undefined behavior works. Anything can happen. That's why you cannot allow it in your code, ever. – Tom Karzes Oct 05 '22 at 06:49

0 Answers0