I hoped I will see the result 65 since 65 is the ASCII value of A.

Why am I getting -1 instead?

#include <stdio.h>

int main()
{
    FILE *fp;
    fp=fopen("first.txt","w");
    putc('A',fp);
    fclose(fp);
    fp=fopen("first.txt","r");
    int x=getw(fp);
    printf("%d\n",x);

    return 0;
}

3 Answers

16
Nikos C. On

You are writing one byte to the file, but then try to read sizeof(int) bytes back from it. getw() returns EOF because of that, and the value of EOF is -1.

For this reason, when using getw() you should examine the file handle using ferror() to be able to tell whether the value getw() returned is the value read from the file or an error code.

Or better yet, use fread() to read from files. getw() is an old function that's there for compatibility with old code. Or use getc() or fgetc() instead, which always return an unsigned char cast to an int and thus EOF can be easily distinguished:

int x = getc(fp);
if (x == EOF) {
    fputs("Error reading from file.\n", stderr);
} else {
    printf("%d\n",x);
}
6
pasignature On

Oh, I see you have a problem right there with "w" just change "w" to "c" and smile. Actually, you're on the right track. Just change getw() to getc().

The output is -1 because you are using getw() function to read a .txt file that contains a char whereas, getw() function reads an integer from file. So the right function to use is getc() function because you have a char in your .txt file. getc() function reads character from file.

Copy and paste even faster:

#include <stdio.h>

int main()
{
    FILE *fp;
    fp=fopen("first.txt","w");
    putc('A',fp);
    fclose(fp);
    fp=fopen("first.txt","r");
    int x=getc(fp);
    printf("%d\n",x);

    return 0;
}

This would output 65.

2
H.S. On

You are getting -1 because getw() reads the next word from the stream (the size of a word is the size of an int and may vary from machine to machine) but in you case, when it try to read word from file it encounters EOF and the end-of-file indicator for the stream is set and getw() returns EOF. Note that EOF is a macro which expands to an integer constant expression with type int and an implementation dependent negative value but is very commonly -1.

You should use putw() to write the file, if you want to use getw() to read the file.

To show you the difference in file when using putc() and putw() to write the file:

When using putc():

putc('A',fp);

check the size of file:

# ls -lh first.txt
-rw-r--r--  1 <owner>  <group>     1B May 11 18:02 first.txt
                                   ^
                                   |
                                size: 1 byte

When using putw():

putw('A', fp);   // the first parameter type of putw() is int and the character will implicitly promoted to int

check the size of file:

# ls -lh first.txt
-rw-r--r--  1 <owner>  <group>     4B May 11 18:00 first.txt
                                   ^
                                   |
                                size: 4 bytes

If using putw():

#include <stdio.h>

int main(void) {
    FILE *fp;

    fp = fopen("first.txt", "w");
    if (fp == NULL) {
        fprintf (stderr, "Failed to open file for write");
        return -1;
    }

    putw('A', fp); // add the error handling for putw()
    fclose(fp);

    fp = fopen("first.txt", "r");
    if (fp == NULL) {
        fprintf (stderr, "Failed to open file for read");
        return -1;
    }

    int x = getw(fp);

    if (feof(fp)) {
        printf ("End of file reached\n");
    }
    else if (ferror(fp)) {
        printf ("Error occurred\n");
    }
    else {
        printf ("%d\n", x);
    }

    return 0;
}

Output:

# ./a.out
65