0

I am new to C and to programming in general. I would like to write a C program that will read the contents of a text file and print it to the console. I have a text file called test.txt that contains the string "Hi". I have created a C program with the following code:

#include <stdio.h>

main()
{
  FILE *myfile;
  myfile=fopen("test.txt", "r");
  printf("%s", myfile);
  fclose(myfile);
}

This program compiles OK (at least with the default settings), but when I run the program, the string "Hi" does not appear. Can you please help me see what I am doing wrong? Thank you.

Also, do you have any C reference websites that you would recommend? I'm looking for a website that contains the C language specification, perhaps including examples of how to use the library functions.

Thank you very much for your time.

Andrew

Carnegie Mellon University

Andrew
  • 1,499
  • 9
  • 25
  • 37

5 Answers5

4

You are trying to print a string at the location pointed to by the value of myfile to the console. That's obviously incorrect (if you don't know why, it's because %s expects a char*, not a FILE*, and a FILE* does not point to the contents of the file.).

To read data from a file, use fread:

char buf[80] = {0}; // fill buf with NULLs
fread(buf, sizeof(char), 2, myfile); // read 2 bytes 

If you want to read the whole file into a buffer, things get slightly more involved, because you have to determine the length of the file and then dynamically allocate memory on the heap of the right size to hold the file. There's a good tutorial on the fread page at cplusplus.com.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
1

This is because that you do not read the file. To read a file, you can use the methods fread or fgets

Dimitri
  • 8,122
  • 19
  • 71
  • 128
1

To read a line, it would make more sense to use fgets since it reads up to the line terminator (\n).

char line[256]
fgets(line, sizeof(line), file);
printf("%s", line);
Marlon
  • 19,924
  • 12
  • 70
  • 101
1

This is the safest way to do it.

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

main()
{
  FILE *myfile;
  char buf[80];
  myfile=fopen("test.txt", "r");
  while(!feof(myfile)){
    memset(buf, 0, 80);
    fread(buf, sizeof(char), sizeof(char)*79, myfile);
    printf("%s", buf);
  }
  fclose(myfile);
}

feof checks to make sure that end of file has not been reached. memset, sets everything in the buffer to 0. fread will read up to 79 chars from the file into the buffer. Note that the max size should be 79 and not 80, the size of the buffer. This is because the last spot in the array should be reserved for the null character '\0', which indicates to C that the string has ended.

Do not use fgets. This function is considered to be unsafe because it can lead to buffer overflows, in which characters are written past the memory space allocated for the string.

If you are new to programming in general, I would suggest learning a more beginner-friendly language like Python before learning C. C is considered to be tricky for new programmers because it does not have automatic memory management, object-oriented programming features, or a large standard library.

Zhehao Mao
  • 1,789
  • 13
  • 13
0

The problem is that you are trying to print the FILE pointer instead of the contents of the file - you need a variable to store this.

It's been interesting to see other approaches. Here is an implementation with fscanf() -

#include <stdio.h>
#define FILENAME "test.txt"

int main(void)
{
    FILE *myfile;
    char string[81] = {'\0'};

    myfile=fopen(FILENAME , "r");
    if(myfile == NULL)
    {
        printf("The file test.txt could not be found! Exiting...\n");
        return -1;
    }
    while(fscanf(myfile, " %80[^\n]s", string) != EOF)
    {
        printf("%s\n", string);
    }
    fclose(myfile);

    return 0;
}

When you open a file, if the operation fails NULL will be returned, it's good practice to check this explicitly so that you know what's gone wrong.

fscanf() returns the number of successful reads (it would be 1 here, for 1 conversion to a string), or EOF if the end of file has been reached. The format string uses a space first of all to remove any and all preceding whitespace (newlines, spaces, tabs) in the input stream.

Using a field width specifier (the 80) in scanf() functions means that only this many characters will be read, so that the input can't go past the allocated space - useful!

The [^] means that the stream will be read only up to encountering the specified characters. [^\n] is a way of getting strings with whitespace in them, as the scanf() family usually only reads up to encountering whitespace for strings. Note that the newline will not be removed (it's still first in the stream).

It then prints the string, with a newline added. This program will loop through as many lines (of up to 80 chars, separated by newlines) are in the file. If you wanted to keep the lines you could make string an array of char arrays and increment each time. This is where the first space in the fscanf() format string comes in handy, it will remove the newline character (and any other preceding whitespace) that is still at the beginning of the stream.

I haven't found any definitive tutorials for learning C online, but there are plenty available. The current standard isn't beginner friendly but a draft form is freely available: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

Another good resource (but not a tutorial) is http://c-faq.com/

The best reference for ins and outs of standard library functions that I've found is Harbison & Steele's C: A Reference Manual - but unfortunately it's not free.

thelionroars1337
  • 188
  • 1
  • 3
  • 10