0

I've got problem regarding output/input from files. Here is my program:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    FILE * out;
    out=fopen("tmp.txt", "w");
    for(int i=0; i<256; i++)
    {
        fprintf(out, "%c", char(i));
    }
    fclose(out);
    FILE * in;
    in=fopen("tmp.txt", "r");
    while(!feof(in))
    {
        char a=fgetc(in);
        cout<<int(a)<<endl;
    }
    fclose(in);
}

and here is the output:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-1

Why is it stopping so quickly? Does that mean char(26) is EOF? How could i write to file (of any type) to overcome this problem?
What I'm looking for is a way to freely write values (of any range, can be char, int or sth else) to a file and then reading it.

miszcz2137
  • 894
  • 6
  • 18
  • 1
    Other than the gratuitous use of `std::cout` and (the misuse of) `std::endl` this is a C question. Change your console output to use `printf` and put in a C tag; you'll get much better answers. In C++, file I/O is done through `std::ifstream` and `std::ofstream`. – Pete Becker Jul 25 '17 at 12:01
  • For file I/O in C++, you may want to use [std::ifstream and std::ofstream](http://www.cplusplus.com/doc/tutorial/files/) – HatsuPointerKun Jul 25 '17 at 12:02
  • 3
    You should not use `char` for the return of `fgetc`. Its return type is `int`. Your return of `-1` means the character you read could very well be the character `0xFF`. `EOF` is usually defined as the integer `-1`. You can't differentiate between them in the current form. – Lanting Jul 25 '17 at 12:03
  • 1
    `fprintf` is for formatted text. You should probably use `fputc` for binary data. – Lanting Jul 25 '17 at 12:04
  • 2
    [Why should I not `#include `?](https://stackoverflow.com/q/31816095/1848654), [Why is `while ( !feof (file) )` always wrong?](https://stackoverflow.com/q/5431941/1848654) – melpomene Jul 25 '17 at 12:09

2 Answers2

3

Works for me *), however a few remarks:

  1. You should not use #include <bits/stdc++.h>, that is an internal header intended for compiler use, not to be included from the client apps.
  2. As some characters are translated (e.g. EOL) or specifically interpreted in the text (default) mode, you should open the files in binary mode.
  3. Reading as (signed) char and converting to int will result in negative values past 127.
  4. As fgetc already returns int, you actually do not need to do that conversion to signed char and back at all.

See here the code with the corrections.

*) Apparently as mentioned in other comments it might not work on Windows in text mode (see the point 2.).

EmDroid
  • 5,918
  • 18
  • 18
3

What I'm looking for is a way to freely write values (of any range, can be char, int or sth else) to a file and then reading it.

In this case you must:

  • Separate the individual values with a delimiter, such as space or new-line symbol.
  • Read back integers rather than individual separate characters / bytes.

The easiest is to use C++ std::fstream for that. E.g.:

int main() {
    {
        std::ofstream out("tmp.txt");
        for(int i=0; i<256; i++)
            out << i << '\n';
        // out destructor flushes and closes the stream.
    }

    {
        std::ifstream in("tmp.txt");
        for(int c; in >> c;)
            std::cout << c << '\n';
    }
}
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • i know but that's memory inefficient – miszcz2137 Jul 25 '17 at 12:16
  • 2
    @miszcz2137 Compared to what and where exactly? – Maxim Egorushkin Jul 25 '17 at 12:17
  • im trying to save char value in one character but Your code is using up to four. – miszcz2137 Jul 25 '17 at 12:20
  • @miszcz2137 a "char value" is one character. Where does the "four" come from ? – 463035818_is_not_an_ai Jul 25 '17 at 12:21
  • I think he means that in the file the int together with newline takes up to 4 (actually 5 on Windows) characters. In that case you can use chars as well: http://coliru.stacked-crooked.com/a/4faac5e1009ec8a5 (note that the char is read as unsigned to avoid negative values past 127) – EmDroid Jul 25 '17 at 12:24
  • @tobi303 cause if you have i=255 there are four characters tt store it : '2', '5', '6', '\n' – miszcz2137 Jul 25 '17 at 12:26
  • But actually if you really are *"looking for a way to freely write values"* (int, char etc.), then it is the easiest way to write as in the post; if you want a "filesize efficient" way of doing that, you'll need to look for binary file serialization/deserialization techniques. – EmDroid Jul 25 '17 at 12:31
  • @miszcz2137 Oh, you are treating `char` as byte, yet you use formatted output function `fprintf`. Which suggest to the reader of your code that your output format is human-readable. For binary format people normally use `fwrite`/`fread`. – Maxim Egorushkin Jul 25 '17 at 14:58