Search code examples
cstringfile-ioscanftext-parsing

Odd glitches occurring when trying to replace word in a file


This question is split into 3 parts : 'The Idea', 'Assumptions' and 'Code MRE', so that you may help point my follies clearly, quickly and with least hassle, and also since, in descending order of frequency, most mistakes lie in the algorithm, the assumptions made during implementation and then in the actual code.

The Idea :

  • Parse through file, at every blank space char (' ' or '\t' or '\n' or '\0', increment iand store the blank space char in an int arr EOW[i] (so that even \0 can be read).
  • rewind FILE *. int q =1;
  • for int q < i:
  • fscanf() every word (word = sequence of chars seperated by blank space chars) and store to buffer[].
  • if strcmp(buffer, target)==0 then strcpy(buffer, replacement).
  • fprintf() buffer followed immediately by char at EOW[q] to temp file.
  • remove original file and rename temp file.

Assumptions :

  • fscanf(%s) will scan and store character until encountering ' ', '\t', '\n', and '\0' chars.
  • char when stored to int arr is stored as its ASCII val, and element of int arr when stored to char is stored as its ASCII character.
  • Usage & incrementation of counters i and q as well as usage for accessing array elements is correct, even if a tad bit twisted.

Code M.R.E :

int main(){
    char frep[261]; getf scanf("%260[^\n]",frep);eat(); // stores fname in frep[], clears stdin
    FILE * rep = fopen(frep,"r");FILE * tmp = fopen("Temp.Ctt","w");// opens file for reading and tmp for writing
    if(rep==NULL||tmp==NULL){
        perror("\nError ");fclose(rep);fclose(tmp);
    }
    else{
        char target[501]; printf("\n Target : "); scanf("%500s",target);eat(); // gets target word
        char replace[501]; printf("\n Replacement : "); scanf("%500[^\n]",replace);eat();// gets its replacement
        char buffer[501]; long long i=0; int EOW[100000];
        while(1){
            char ch = fgetc(rep);
            if(ch==EOF)
                break; // breaks loop if EOF reached
            else if(ch==' '||ch=='\t'||ch=='\n'||ch == '\0')
                i++;EOW[i]=ch;
        }
        rewind(rep);
        for(int q=1; q<i; q++){
                fscanf(rep,"%500s",buffer);
                if(strcmp(target,buffer)==0)
                    strcpy(buffer,replace);
                fprintf(tmp,"%s%c",buffer,EOW[q]);
        }
        fclose(rep);fclose(tmp);
        remove(frep); rename("Temp.Ctt",frep);
        printf("\nSucess.\n\nReplaced any instances of \"%s\" with \"%s\".\n",target,replace);
    }
    
    return 0;
}

Solution

  •     else if(ch==' '||ch=='\t'||ch=='\n'||ch == '\0')
            i++;EOW[i]=ch;
    

    This is missing the { ... } braces, causing EOW[i]=ch; to fall outside the else if.

        for(int q=1; q<i; q++){
    

    Make that q <= i otherwise it's skipping over the last element, given how EOW is numbered.

    int EOW[100000];

    Unrelated, but you can make that char EOW since there is no good reason for it to be an int.