1

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


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);
}

Two things are happening: the while loop is giving me a segmentation fault. I think after input is because fgetc() returns in an int and I want to convert to a char. And the creation of the second file has a weird dot next to the txt name (see picture).

creation error

Nikki
  • 31
  • 5
  • 2
    What are `inFile` and `outFile`? Please post a [mre] that we can run ourselves. – John Kugelman Sep 25 '22 at 03:32
  • 2
    Does this answer your question? [Why is “while( !feof(file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feoffile-always-wrong) – Avi Berger Sep 25 '22 at 03:40
  • To answer your question: both inFile and outFile are string of a .txt file name. ie lower.txt containing information that is all uppercase requiring a conversion to lower case. – Nikki Sep 25 '22 at 03:44
  • @AviBerger thank you that makes sense about the while(!feof(pIn). I have at the advisement put an if break with feof(). Yet I am still getting a segmentation fault. Is there anything that I am forgetting? I am new to C. Thank you for the help – Nikki Sep 25 '22 at 03:55
  • 2
    `if (pIn == NULL)` is followed by an error message but the code just keeps going, eventually reaching `fclose(pIn);` or the other operations performed on it which could cause a crash. At least `pOut` failing to open is handled relatively well. You could easily run this in a debugger and narrow down exactly where it is crashing and why. If it crashes in code that isn't yours use the call stack to find your code where the problem starts. – Retired Ninja Sep 25 '22 at 03:55
  • @RetiredNinja the debugger was flagging a segmentation fault at the while initiation now it has moved to``` c=fgetc(pIN)``` yet, the creation of the output file uppper.txt still ahs the weird symbol after it – Nikki Sep 25 '22 at 04:00
  • Since you have not shown where those filenames come from it's hard to say what the problem with them might be. Consider a [mcve]. – Retired Ninja Sep 25 '22 at 04:03
  • 1
    `fgetc(pIn); ` actually returns an int, not a char (This lets it accommodate an out of band return value of EOF. Change c to be of type int and test it against EOF after calling fgetc. char can be signed or unsigned depending on platform. Your conversion of the result of getc to char and then its promotion to int (for the call to tolower) might be producing an illegal input to tolower resulting in an out of bounds array access in tolower which could be your segfault. – Avi Berger Sep 25 '22 at 04:12
  • @AviBerger [Comment](https://stackoverflow.com/questions/73841887/writing-to-a-file-in-c-segmentation-fault/73842061#comment130387364_73841887) is correct. OP's code risk UB. – chux - Reinstate Monica Sep 25 '22 at 04:37
  • @chux-ReinstateMonica, I was just playing with when that could occur. After checking further, it seems the conditions for this failure are a platform on which char is implemented as signed and there is an "extended" character in the file (i.e. outside of a 7 bit encoding). I had a different initial thought about how this could be produced that was wrong. – Avi Berger Sep 25 '22 at 04:48
  • @AviBerger True: `tolower(x)` is is only specified for `int x` in the `unsigned char` range and `EOF`. Else UB. – chux - Reinstate Monica Sep 25 '22 at 04:54
  • Does this answer your question? [Do I need to cast to unsigned char before calling toupper(), tolower(), et al.?](https://stackoverflow.com/questions/21805674/do-i-need-to-cast-to-unsigned-char-before-calling-toupper-tolower-et-al) – autistic Sep 25 '22 at 05:05
  • `fgets` will leave the newline character at the end of the input, generally a bad thing for filenames. [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input) shows how to remove it. – Retired Ninja Sep 25 '22 at 06:47

1 Answers1

1

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?

int c;
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.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256