-3

This is my code, and each letter of the output is being printed twice. It is not the text file and it only happens when I insert my putchar(tolower) statement in but it is formatted exactly as it should be. What is wrong with the statement?

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

#define MAX_STRING_SIZE 20
#define MAX_LIST_SIZE 50

int readFile(char *filename); /* function declaration for readFile, defined below */
void punct();

/* main function */
int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("%s: usage %s textFileName \n", argv[0], argv[0]);
        exit(1);
    }

    readFile(argv[1]);

    return 0;
}

int readFile(char *filename) {
    char ch;
    FILE *fPtr;

    fPtr = fopen(filename, "r"); /*open file filename, r is read only */
    if (!fPtr) {
        return 0;
    }

    while ((ch = fgetc(fPtr)) != EOF) {
        putchar(tolower(ch));
        printf("%c", ch);
    }

    fclose(fPtr);

    return 1; /* because success */
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
math
  • 13
  • 2

2 Answers2

5

each letter of the output is being printed twice

This two lines:

putchar(tolower(ch));
printf("%c", ch); 

Print two times the same character.

putchar puts a character to the standard output.
printf puts a formatted text to the standard output. In your case, the formatted text is the same character printed the line immediately above.

it only happens when I insert my putchar(tolower) statement in

That's because doing that you are actually doubling the output.

skypjack
  • 49,335
  • 19
  • 95
  • 187
0

There are multiple problems in your code:

  • ch must be defined with type int to accommodate all possible return values from fgetc(). These are all values of type unsigned char plus the special value EOF. Storing into a char variable poses multiple problems:

    • The value EOF can no longer be tested accurately. If the type char is unsigned, (ch = fgetc(fp)) == EOF is always false. Conversely, if type char is signed, (ch = fgetc(fp)) == EOF might be true for ch = '\377, a valid byte value.

    • if char is signed, tolower(ch) has undefined behavior for negative values.

  • each byte read from the file is output twice: first by putchar(tolower(ch)); and a second time by printf("%c", ch);.

Here is a corrected version:

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

char *progname;    

int readFile(const char *filename) {
    int ch;
    FILE *fPtr;

    fPtr = fopen(filename, "r"); /* open file filename for reading */
    if (!fPtr) {
        fprintf(stderr, "%s: cannot open %s: %s\n",
                progname, filename, strerror(errno));
        return 1;  /* failure */
    }

    while ((ch = fgetc(fPtr)) != EOF) {
        putchar(tolower(ch));
    }
    fclose(fPtr);

    return 0;  /* success */
}

int main(int argc, char *argv[]) {
    progname = argv[0];
    if (argc < 2) {
        fprintf(stderr, "usage: %s textFileName\n", progname);
        return 1;
    }
    return readFile(argv[1]);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189