Search code examples
csegmentation-faultfwritefreadfeof

Getting segmentation fault in fread/fwrite loop, copying file


I am to copy a file from the inputed source to the inputed destination. I am getting a segmentation fault error about 2 seconds after the destination is entered. The output file is created so fopen() is working.

I looked online and I see a lot of c=getc(fp). I prefer fread() and fwrite() for this question because it's a little more basic.

Code

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

//void rmnewline(char *string);
void remove_last_newline(char *str);

int main()
{
  char x[3];
  x[0]='y';
  int ch;

  while(x[0]=='y'||x[0]=='Y')
  {
    char source[256], destination[256];
    int *a;

    printf("Enter a source file: ");
    fgets(source, 256, stdin);
    if (source[254] == '\n' && source[255] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
    remove_last_newline(source);

    printf("Enter a destination file: ");
    fgets(destination, 256, stdin);
    if (destination[254] == '\n' && destination[255] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
    remove_last_newline(destination);

    FILE *sp, *dp;

    sp = fopen(source, "r");
    if (sp == NULL) { printf("ERROR: Could not open source file."); exit(1); }
    dp = fopen(destination, "w");
    if (dp == NULL) { printf("ERROR: Could not open destination file."); exit(1); }
    while(1)
    {
      fread(a, 1, 1, sp);
      if (feof(sp))
      break;
      fwrite(a, 1, 1, dp);
    }

    fclose(sp);
    fclose(dp);

    printf("Run Again?(y/n):");
    fgets(x, 2, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
 }

}

/*void rmnewline(char *string)
{
    int i, l = strlen(string);

    for(i=0; i<=l; i++)
    {
      if(string[i] == '\0')
         return;
      if(string[i] == '\n')
     {
       string[i] == '\0';
       return;
     }
  }

}*/

void remove_last_newline(char *str) {
    if (*str == '\0') return; /* do nothing if the string is empty */
    while(str[1] != '\0') str++; /* search for the end of the string */
    if (*str == '\n') *str = '\0'; /* if the last character is newline, delete it */
}

Solution

  • fgets store the newline character read in the buffer.

    It may prevent fopen to open "the specified file" and fopen may return NULL.

    Please delete newline characters if they are in the buffer.
    This can be done using this function:

    void remove_last_newline(char *str) {
        if (*str == '\0') return; /* do nothing if the string is empty */
        while(str[1] != '\0') str++; /* search for the end of the string */
        if (*str == '\n') *str = '\0'; /* if the last character is newline, delete it */
    }
    

    please pass source and destination to this function after reading file names to them.