'Can't make changes and save to output file in C

I have a subject where I'm asked to read a c file,convert it's comments from lowercase to uppercase and vice-versa and then save this file with any changes made to another c file(a blank ouput file for example).I have made a code but It doesn't make any changes to comments,instead it saves the original file to the output.c file,any suggestions?

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

int main(){
    char ch;

    FILE *fp1, *fp2;
    char source_file[] = "input2.c";
    char target_file[] = "output.c";
    char str[200];
    fp1 = fopen(source_file, "r");
    fp2 = fopen(target_file, "w");

    while(fgets(str,200,fp1) != NULL){
        int i,j,l;
        int l = strlen(str);
        for(int i = 0; i < l-1; i++){
            if(str[i]=='/' && str[i+1]=='/'){
                for(int j = i+2; j < l; j++){
                    if (str[j] >= 'A' && str[j]<='Z')
                        str[j] = str[j] + 32;
                        else if (str[j] >= 'a' && str[j]<='z')
                        str[j] = str[j] - 32;
                }
            
            }
        
        }
    }

    while ((ch = fgetc(fp1)) != EOF)
      {fputc(ch, fp2);
      printf("File copied successfully.\n");}
    fclose(fp1); 
    fclose(fp2); 

    return 0;
}
c


Solution 1:[1]

The line

while ((ch = fgetc(fp1)) != EOF)

will not work, for two reasons:

  1. The file position indicator is already at the end of the file, because your code will only reach that line after fgets returns NULL.

  2. Even if you move the file position to the start of the file using rewind, your loop will not work, because you made the changes in str, not in the input file. Therefore, you want to write str to the output file, instead of copying the input file.

For the reasons stated above, you should remove that loop and instead insert the line fputs( str, fp2 ); into the fgets loop:

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

int main(){
    FILE *fp1, *fp2;
    char source_file[] = "input2.c";
    char target_file[] = "output.c";
    char str[200];
    fp1 = fopen(source_file, "r");
    fp2 = fopen(target_file, "w");

    while(fgets(str,200,fp1) != NULL){
        int l = strlen(str);
        for(int i = 0; i < l-1; i++){
            if(str[i]=='/' && str[i+1]=='/'){
                for(int j = i+2; j < l; j++){
                    if (str[j] >= 'A' && str[j]<='Z')
                        str[j] = str[j] + 32;
                        else if (str[j] >= 'a' && str[j]<='z')
                        str[j] = str[j] - 32;
                }
            }
        }

        //INSERTED_CODE
        fputs( str, fp2 );
        //INSERTED CODE
    }

    fclose(fp1); 
    fclose(fp2); 

    return 0;
}

For the input

This is a test. //This is a test.

the program has the following (correct) output:

This is a test. //tHIS IS A TEST.

By the way, this is how I would write the solution:

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

#define  INPUT_FILENAME "input2.c"
#define OUTPUT_FILENAME "output.c"

int main( void )
{
    FILE *fp1, *fp2;
    char line[200];

    //attempt to open input file
    fp1 = fopen( INPUT_FILENAME, "r" );
    if ( fp1 == NULL )
    {
        fprintf( stderr, "Error opening input file!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to open input file
    fp2 = fopen( OUTPUT_FILENAME, "w" );
    if ( fp2 == NULL )
    {
        fprintf( stderr, "Error opening output file!\n" );
        exit( EXIT_FAILURE );
    }

    //read one line per loop iteration
    while( fgets( line, sizeof line, fp1 ) != NULL )
    {
        char *p;

        //verify that input buffer was large enough to fit
        //the entire line
        if ( strchr( line, '\n' ) == NULL )
        {
            fprintf( stderr, "Line was too long for input buffer!\n" );
            exit( EXIT_FAILURE );
        }
        
        //determine whether line contains comment
        if ( ( p = strstr( line, "//" ) ) != NULL )
        {
            //skip the "//"
            p += 2;

            //make comment upper-case
            for ( ; *p != '\0'; p++ )
            {
                //reverse the case if character is alphabetical
                if ( islower( (unsigned char)*p ) )
                    *p = toupper( (unsigned char)*p );
                else if ( isupper( (unsigned char)*p ) )
                    *p = tolower( (unsigned char)*p );
            }
        }

        //write (possibly modified) line to output file
        fputs( line, fp2 );
    }

    //cleanup
    fclose(fp2);
    fclose(fp1);

    return EXIT_SUCCESS;
}

Note however that there are two possible comments in C:

  1. single-line comments //
  2. multi-line comments /* and */

You seem to be only handling the first type of comment. If you want to also be able to handle the second type of comment, then the solution would be more complicated (but also possible).

Solution 2:[2]

You are reading in each line into str and modifying it inside the while loop. However, you are never writing that modified content to the new file or saving it anywhere.

There are a couple ways you could do this. I would recommend writing each line inside the while loop.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 maxrzaw