-2

So basically, in the code below I try to read the file names (i.e. input.txt and output.txt) from the keyboard but I get "segmentation fault". The program also converts the lower-case letters into upper-case letters and the upper-case letters into lower-case letters. Any suggestions? What am I doing wrong?

#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() 
{

  char c;
  int charToLowerCase = 0;
  int charToUpperCase = 0;
  int countCharacters = 0;
  FILE *in_file = NULL;
  FILE *out_file = NULL;
  char str_in[100];
  char str_out[100];
  char *s_in = NULL;
  char *s_out = NULL;

  gets(str_in);
  gets(str_out);

  if (s_in != NULL)
   in_file = fopen(str_in, "r");

  if (s_out != NULL)
   out_file = fopen(str_out, "w");

  c = fgetc(in_file);
  while (c != EOF)
  {
    if (c >= 'A' && c <= 'Z')
    {
     fprintf(out_file, "%c", tolower(c));
     charToLowerCase++;
    }
    else if (c >= 'a' && c <= 'z')
           {
            fprintf(out_file, "%c", toupper(c));
            charToUpperCase++;
           }    
    else
     fprintf(out_file, "%c", c);

    c = fgetc(in_file);
    countCharacters++;
  }
  fprintf(out_file, "\n");
  fprintf(out_file, "Read %d characters in total, %d converted to upper-case, %d to lower-case.\n", countCharacters, charToUpperCase, charToLowerCase);

  fclose(in_file);
  fclose(out_file);
  return 0;
}
  • `c` should be an `int`; you could also also use `isupper()` and `islower()` – pzaenger Oct 11 '16 at 09:14
  • 1
    You don't actually open the files, and then attempt to read and write through them. You test if `s_in != NULL` instead of `s_in == NULL`, though you would not even need to test; you know already that it is NULL at that point + they have nothing to do with `fopen(str_in, ...)`. – Ilja Everilä Oct 11 '16 at 09:16
  • 1
    Nobody should ever use `gets()`. Please change `gets(str_in);` to `fgets(str_in, sizeof str_in, stdin);`. – unwind Oct 11 '16 at 09:18

2 Answers2

0

There is no proper handling for s_in == NULL and s_out == NULL, the flow continues in all cases:

if (s_in != NULL)
   in_file = fopen(str_in, "r");

if (s_out != NULL)
   out_file = fopen(str_out, "w");

The crash occurs in my tests on the following line:

  c = fgetc(in_file); 

because in_file==NULL

GMichael
  • 2,726
  • 1
  • 20
  • 30
0

You want this:

int main() 
{
  int c;                        //<<< int instead of char
  int charToLowerCase = 0;
  int charToUpperCase = 0;
  int countCharacters = 0;
  FILE *in_file = NULL;
  FILE *out_file = NULL;
  char str_in[100];
  char str_out[100];

  gets(str_in);
  gets(str_out);

  in_file = fopen(str_in, "r");
  if (in_file == NULL)
  {
    // file could not be opened
    printf ("Could not open file %s\n", str_in);
    return 1;
  }

  out_file = fopen(str_out, "w");
  if (in_file == NULL)
  {
    // file could not be opened
    printf ("Could not open file %s\n", str_out);
    return 1;
  }

  ...
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Thanks ! It works! but I get this warning though: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations] gets(str_out); – Raluca Damaris Lupeş Oct 11 '16 at 09:31
  • 1
    `gets` is deprecated, you should't use it anymore. Use `fgets` instead. [Read this](http://stackoverflow.com/questions/30890696/why-gets-is-deprecated) for more information. – Jabberwocky Oct 11 '16 at 09:33
  • I am trying to use fgets(str_in, 100, stdin);..but it says "Could not open the file" – Raluca Damaris Lupeş Oct 11 '16 at 09:52
  • @RalucaDamarisLupeş that's another question. Ask a new question specifically about this issue. And before read this: [MCVE]. – Jabberwocky Oct 11 '16 at 10:01
  • 1
    @RalucaDamarisLupeş Your `fgets(...)` reads from `stdin` instead of the file. That's why it couldn't open the file. – progyammer Oct 11 '16 at 10:26