I somehow got an integer repeated...

So I wrote this code. I was required to:
Write into a new text file all integers between [1,16].
Output only those numbers inside the text file that are smaller than 15.
Output an arithmetic mean of those numbers of the new file that are smaller than 11.
Put into another new file all the numbers that are not possible to divide by 3.
Output all the numbers from the another new file.

When I run this, the first file is alright, another has a 16 integer repeated at the end.

I don't know what should I do. I tried changing it a bit (mainly in array size and the value of i) but then the first file seems to have the same problem.


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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>

using namespace std;

int main()
{

    int T[17];
    int sum = 0;
    int average;

    int important;

    int evenmoreimportant;
    ofstream outputf;
    ifstream inputf;
    outputf.open("exemplar.txt");

        for(int i = 1; i < 17; i++)
        {
        T[i] = i;
        outputf << T[i]<<'\n';
        }
        outputf.close();



        if(inputf.fail())
        {
                    cerr <<"ERROR"<<endl;
                    exit(1);
        }


        inputf.open("exemplar.txt");
        while(!inputf.eof())
        {
        inputf >> important;
        if(important<15)
        {
             printf("%8d\n", important);
        }
        if(important<11)
        {
            sum = sum + important;
            average = sum / important;
        }
        }
        inputf.close();


        outputf.open("newfile.txt");
        inputf.open("exemplar.txt");
        while(!inputf.eof())
        {
            inputf >> evenmoreimportant;
        if(!(evenmoreimportant % 3 == 0))
        {
            outputf << evenmoreimportant << '\n'<<endl;
            printf("%d\n", evenmoreimportant);
        }
        }
        inputf.close();
        outputf.close();




cout<<"Average of those numbers that are smaller than 11: "<<average<<endl;

return 0;
}
It is because you are looping on EOF, line 39. Don't do that.
Also, please watch your indentation. It will save you a lot of grief later.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
        inputf.open("exemplar.txt");
        while(inputf >> important)
        {
                if(important<15)
                {
                     printf("%8d\n", important);
                }
                if(important<11)
                {
                    sum = sum + important;
                    average = sum / important;
                }
        }
        inputf.close();

Hope this helps.
Well, as I expected the result is exactly the same, sadly.
What's the point of line 24 ?
Why don't you just write i to the file?

Also it would be much better to use functions for each task - if you are allowed - or at least structure your main function.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
  // Task 1
  // Write into a new text file all integers between [1,16].
  ofstream outputf("exemplar.txt");
  if (!outputf.is_open())
  {
    cerr << "\a\nError creating file \n";
    return -1;
  }
  for (int i = 1; i < 17; i++)
  {
    outputf << i << "\n";
  }
  // End Task 1  
  return 0;
}
Hello Gieniusz Krab,

This is what I see with your program:

Is this a C or C++ program?
#include <cstdio> is not needed here. And I do not see where #include <algorithm> is used anywhere.

Consider this bit of code:

1
2
3
4
5
6
7
8
        if(inputf.fail())
        {
                    cerr <<"ERROR"<<endl;
                    exit(1);
        }


        inputf.open("exemplar.txt");

How do you check if a file is open before it is opened? It does work and does not cause any problem with the way the program works for now, but some day in another program it could be a problem.

In the code:
1
2
3
4
5
6
        if(important<11)
        {
            sum = sum + important;
            average = sum / important;
        }
        }

Not the way do do the average. This should be done after the while loop. Also I would suggest making "average" a double and not an int. This would give a more accurate number for the average with the division. Dividing by "important" does work for this program, but for different numbers it will fail. See later code for what I changed.

The "printf" statements can easily be changed with the "cout" statements I changed to. The use of "std::setw(?)" needs the header file "iomanip".

This is your program with the changes I made. Notice the comments in the program.

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <fstream>
#include <iomanip> // <--- for setw().

int main()
{
        // <--- Always initialize your variables.
	int T[17]{ 0 };  // <--- It will initialize the whole array to 0.
	int sum = 0;
	int count{ 0 };  // <--- Added this variable.
	double average{ 0 };  // <--- Changed to double.

	int important{ 0 };

	int evenmoreimportant{ 0 };

	std::ofstream outputf;
	std::ifstream inputf;

	outputf.open("exemplar.txt");

	for (int i = 1; i < 17; i++)
	{
		T[i] = i;
		outputf << T[i] << '\n';
	}
	outputf.close();

	inputf.open("exemplar.txt");
	
	if (inputf.fail())
	{
		std::cerr << "ERROR" << std::endl;
		exit(1);
	}

	while (inputf >> important)
	{		
		if (important < 15)
		{
			//printf("%8d\n", important);
			std::cout << std::setw(8) << important << std::endl;
		}

		if (important < 11)
		{
			sum += important;  // <--- Same as sum = sum + important.
			count++;
		}
	}
	
       // <--- The "static_cast" is to make sure the division is done by doubles not ints.
	average = static_cast<double> (sum) / static_cast<double> (count);

	inputf.close();


	outputf.open("newfile.txt");
	inputf.open("exemplar.txt");

	while (inputf >> evenmoreimportant)
	{
		if (!(evenmoreimportant % 3 == 0))
		{
			outputf << evenmoreimportant << std::endl;
			//printf("%d\n", evenmoreimportant);
			std::cout << std::setw(3) << evenmoreimportant << std::endl;
		}
	}

	inputf.close();
	outputf.close();

	std::cout << std::fixed << std::showpoint << std::setprecision(2);
	std::cout << "\nAverage of those numbers that are smaller than 11 is: " << average << std::endl;

        // Something here to keep the window open if you need it.
        // See http://www.cplusplus.com/forum/beginner/1988/

        return 0;
}


One last point using namespace std; is not a good practice. It WILL get you in trouble some day.

Hope that helps,

Andy
Ok, but...

How does changing one !inputf.eof() into inputf >> someinteger does not help but replacing both of them solves the problem?

What's the point of using !inputf.eof() then? How did it print me an extra number?
Also, doesn't if(!inputf.fail()) apply to all the files and therefore I could put it anywhere?
Hello Gieniusz Krab,

Consider your original code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(!inputf.eof())
{
    inputf >> important;

    if(important<15)
    {
         printf("%8d\n", important);
    }

    if(important<11)
    {
        sum = sum + important;
        average = sum / important;
    }
}


When you check the while condition itis not at EOF yet so you enter the while loop. It reads from the file and gets the last bit of information and then processes that information before going back to the while condition. Which is still not in an EOF state yet. After entering the while loop the first instruction is to read from the file and this time there is nothing left to read, so the EOF bit of the stream is set along with the fail bit, but being inside the while loop the information will be processed with the last information in the variable(s) making it look like there is a duplicate at the end.

Changing the while condition to: while (inputf >> important) when the read fails the while condition will fail and the while loop will be passed over.

Twenty years ago when I was learning C checking for EOF was the norm, but things have changed since then. This new condition for the while loop tends to be the norm today. This is most likely do to the new C++ standards that are in place today.

How does changing one !inputf.eof() into inputf >> someinteger does not help but replacing both of them solves the problem?

Because they are separate. The idea here is to show you one example and hope that you understand and learn to change anything else that would apply.

Also, doesn't if(!inputf.fail()) apply to all the files and therefore I could put it anywhere?

The concept does apply to all files that are opened, but not really anywhere. It would best be used after an input statement like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        while(!inputf.eof())
        {
           inputf >> important;

           if(!inputf.fail())  // <--- or if(!inputf.eof())
               break;  // <--- Breaks out of the while loop.

           if(important<15)
           {
               printf("%8d\n", important);
           }

          if(important<11)
          {
               sum = sum + important;
               average = sum / important;
          }
        }


Hope that helps,

Andy
Thank you Andy!

I'm glad you can explain stuff in a clear way.
Hello Gieniusz Krab,

Your welcome. Glad I could help.

Cheers,

Andy
Topic archived. No new replies allowed.