ifstream doesn't read from the file

I wrote a program which was supposed to decrypt a file encrypted with the XECryption algorithm. Now, I know the decryption algorithm, but I have a problem with my ifstream object. It doesn't read anything at all, and the ofstream object just outputs a single random byte in a never ending loop. I've tried using cin, which works correctly, but it's not what I want.

Here's the code:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <fstream>
#include <iostream>

using namespace std;
int main()
{
    ifstream in("file.in", ios::in);
    if (!in.is_open())
    {
        cout << "File didn't open!\n";
        in.close(); /* I'm a little unsure about this. If the file didn't open,
do I really have to close it? */
        cin.get();
        return 0;
    }
    if (in.fail())
    {
        cout << "File failed before reading!\n";
        in.close();
        cin.get();
        return 0;
    }

    ofstream out("file.out");

    int one;
    int two;
    int three;
    int byte;

    while (!in.eof())
    {
        in >> one >> two >> three;
        byte = one + two + three;
        out << (char) byte;
    }

    cout << "Closing file!\n";
    in.close();
    out.close();
    cin.get();
    return 0;
}


I'm doing this on a Windows 8(.1) pc with Code::Blocks 13.12. In the file (file.in) I have replaced the points with spaces. What is wrong with the code?
Last edited on
!fail() means "nothing failed".
How embarassing, hypercorrection! I still have problems though; when I remove the exclamation mark, the object in does not fail, but my out object just writes a single byte in file.out in a never ending loop. In this case 'ยข'.

I still think it's the in object that's the problem. If I use cin instead, I don't have the same problem.
Try this

1
2
3
4
5
while(in >> one >> two >> three)
{
	byte = one + two + three;
	out << (char) byte;
}


And for the other question, no you don't have to explicitly call the close function. The destructor of the ifstream takes care of that after it goes out of scope.
I don't get the loop with that code, thank you, but the program goes directly to "Closing file!".
I tried the following code in Turbo C++ 1.01 (oh yes, the DOS version):

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
26
27
28
29
30
31
32
33
#include <fstream.h>
#include <iostream.h>

int main()
{
    ifstream in("file.in");
    if (in.fail())
    {
        cout << "File failed before reading!\n";
        in.close();
        cin.get();
        return 0;
    }

    ofstream out("file.out");

    int one;
    int two;
    int three;
    int byte;

    while(in >> one >> two >> three)
    {
        byte = one + two + three;
        cout << (char) byte;
    }

    cout << "Closing file!\n";
    in.close();
    out.close();
    cin.get();
    return 0;
}


Still no dice. The program writes nothing to file.out. Well, I have have at least excluded any problems with either Code::Blocks or GCC.
The program writes nothing to file.out.
That's because the out stream is opened and closed but otherwise not used.

I'm not familiar with the XECryption algorithm, but from what I can gather, the encrypted data looks like this:
.38.32.30.24.37.39

that is, a set of three integers separated by dots.

When reading from the file, you need to account for those separators:
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
26
27
28
29
30
31
32
33
34
#include <fstream.h>
#include <iostream.h>

int main()
{
    ifstream in("file.in");
    if (in.fail())
    {
        cout << "File failed before reading!\n";
        cin.get();
        return 0;
    }

    ofstream out("file.out");

    int one;
    int two;
    int three;
    char byte;
    char dot;

    while(in >> dot >> one >> dot >> two >> dot >> three)
    {
        byte = one + two + three;
        cout << byte;    // to console
        out << byte;     // to file
    }

    cout << "Closing file!\n";
    in.close();
    out.close();
    cin.get();
    return 0;
}

(That's Turbo C++ code, please modify accordingly if using a recent compiler).

Edit
:
In the file (file.in) I have replaced the points with spaces.
Oops, I overlooked that.
Last edited on
Chervil wrote:
That's because the out stream is opened and closed but otherwise not used.


Yes, sorry about that. I have tried with both out and cout, but there is no output either in file.out or on the screen. That indicates an error with in, I think.

that is, a set of three integers separated by dots. When reading from the file, you need to account for those separators:


Yes, as you realised later, I had replaced the dots with spaces, but I did try your alternative now, just to be sure (after replacing the spaces with dots again, of course). Still nothing.
But the code I posted worked - using Turbo C++ 3.0 and the very limited data file which I posted (contained only two characters after decrypting).

Here's a modified version. It is standalone, using no files, and should work with current C++ compilers.
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
26
27
28
29
30
31
#include <iostream>
#include <sstream>

int main()
{
    std::istringstream in(".38.32.30.24.37.39");
    
    if (in.fail())
    {
        std::cout << "File failed before reading!" << std::endl;
        std::cin.get();
        return 0;
    }

    int one;
    int two;
    int three;
    char byte;
    char dot;

    while(in >> dot >> one >> dot >> two >> dot >> three)
    {
        byte = one + two + three;
        std::cout << byte;    // to console
    }

    std::cout << "\nDone" << std::endl;
    std::cin.get();
    
    return 0;
}


output:
dd
Done

Last edited on
Chervil wrote:
But the code I posted worked - using Turbo C++ 3.0 and the very limited data file which I posted (contained only two characters after decrypting).


Success! I realised there was nothing wrong with the program itself, but the text file wasn't ANSI encoded. I'm sorry for this meaningless thread, but at least you taught me not to use the eof() method.

This code worked in Code::Blocks:

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
26
27
28
29
30
31
32
33
34
35
#include <fstream>
#include <iostream>
using namespace std;

int main()
{
    ifstream in("file.in");
    if (in.fail())
    {
        cout << "File failed before reading!\n";
        cin.get();
        return 0;
    }

    ofstream out("file.out");

    int one;
    int two;
    int three;
    char byte;
    char dot;

    while(in >> dot >> one >> dot >> two >> dot >> three)
    {
        byte = one + two + three;
        cout << byte;    // to console
        out << byte;     // to file
    }

    cout << "\nClosing file!\n";
    in.close();
    out.close();
    cin.get();
    return 0;
}
Topic archived. No new replies allowed.