Writing to a file in C segmentation Fault

Viewed 31

I have a function that gets a string from the user and then does the following

FILE *pIn;
FILE *pOut;
pIn = fopen(inFile, "r");
char c;
if (pIn == NULL)
{
    printf("File not found");
}
pOut = fopen(outFile, "w");
if (pOut == NULL)
{
    fclose(pIn);
    printf("The write file cannot be opened.\n");
    exit(1);
}
else{
    while(!feof(pIn)) //while it is not the end of input file
    {
        c = fgetc(pIn);
        c = tolower(c);
        fputc(c,pOut);
        //fprintf(pOut,c);
    }
    fclose(pOut);
}
fclose(pIn);

Two things are happening: the while loop is giving me a segmentation fault. And the creation of the second file has a weird dot next to the txt name (see picture).

creation error

2 Answers

At least these problems

Missing .h

Add

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

Wrong type

fgetc() returns an int to handle the typical 257 different return values. @Avi Berger

// char c;
int c;

Using a char value that is negative and not EOF is undefined behavior with tolower(). By saving in int, c will have a value in the unsigned char range or EOF.

while(!feof(pIn)) wrong

Why is “while( !feof(file) )” always wrong?

while((c = fgetc(pIn)) != EOF) {
  c = tolower(c);
  fputc(c,pOut);
}

Error lacks exit

When pIn == NULL, no point in continuing. @Retired Ninja

if (pIn == NULL) {
  printf("File not found");
  exit(1); // Add
}

Without an early exit, fclose(pIn); is undefined behavior as pIn==NULL.

Bad file name

OP has "creation of the second file has a weird dot next to the txt name". Certainly due to improper filename formation like insufficient buffer size for the name.

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_NAME 256
void TraverseFile(char *inFile, char *outFile);
int main(int argc, char *argv[]) \
{
char *old; 
    char *new; 
    if (argc < 3)
    {
        old = (char *)malloc(MAX_NAME+1);
        if (old ==NULL)
        {
            return 1;
        }
        new = (char *)malloc(MAX_NAME+1);
        if (new == NULL)
        {
            return 1;
        }
        printf("Enter file to convert to lower: ");
        fgets(old, MAX_NAME, stdin);
        printf("\n");
       printf("Enter name to export into: ");
        fgets(new, MAX_NAME, stdin);
    }
    else{
        old = argv[1];
        new = argv[2];
        printf("This program %s is reading %s and writing into %s",
        argv[0], old,new);
    }
    TraverseFile(old,new);
}
void TraverseFile(char *inFile, char *outFile)
{
    FILE *pIn;
    FILE *pOut;
    pIn = fopen(inFile, "r");
    char c;
    if (pIn == NULL)
    {
        printf("File not found");
    }
    pOut = fopen(outFile, "w");
    if (pOut == NULL)
    {
        fclose(pIn);
        printf("The write file cannot be opened.\n");
        exit(1);
    }
    else{
        while(1) //while it is not the end of input file
        {
            c= putchar(tolower(fgetc(pIn)));
            if (feof(pIn)) break;
            fputc(c,pOut);
        }
        fclose(pOut);
    }
    fclose(pIn);
}

Full code... still has weird symbol next to newly created file and does not compile because of int to char in fgetc(). yet requirment is to use tolower(). tolower converts char and returns int yet I feel like I am too new at C to understand or help.

Related