HELP!!

I am stuck with this question..hope someone could guide me along! Thank you
Problems:
1. I do not know how to generate r [i].even,r [i].odd,r [i].sum,r [i].digit <- count the number of digits in the rand().
2. I could not generate a output file with info, if I run with my code, the output file would be blank.

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
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;


const int MAX = 100;

struct Number
{
int No;
int odd;
int even;
int sum;
int digit;
char type;

};


// 1. Create a text file that describes
// some rational numbers
void constructInfile (fstream&, char []);
// 2. From text file to array of rational numbers
int fileToArray (fstream&, char [], Number []);
// 3. Process the array
void processArray (Number [], int);
// 4. Array to output file
void arrayToOutfile (Number [], int, ofstream&, char []);
int main ()
{
    fstream afile;
    char fileName [MAX];
    cout << "Enter rational no file name: ";
    cin >> fileName;
	
    srand (time (NULL));
	
	
    constructInfile (afile, fileName);
    cout << "-------------------------------" << endl;
    Number r [MAX];
    int size = fileToArray (afile, fileName, r);
    cout << "-------------------------------" << endl;
    processArray (r, size);
    cout << "---------------v---------------" << endl;
    ofstream outfile;
	
	
    cout << "Enter the output file name: ";
    cin>> fileName;
	
	
    arrayToOutfile (r, size, outfile, fileName);
}
	
	
void constructInfile (fstream& afile, char fileName [])
{
    afile.open (fileName, ios::out);
    if (!afile)
    {
        cout << fileName
        << " opened for creation failed"
        << endl;
        exit (-1);
    }


cout << fileName << " opened for creation OK" << endl;

//Creating input in file generate the column Numbers i and 2 rows of random numbers
//
int size = rand () % 51 + 50;
for (int i = 1; i <= size; i++)
{
    afile << "Numbers "
    << i<< "\t" << rand ()
    << endl;
}
afile.close ();
cout << fileName << " successfully created" << endl;
}

//Transferring input to Array
//
int fileToArray (fstream& afile, char fileName [], Number r [])
{
    afile.open (fileName, ios::in);
    if (!afile)
    {
         cout << fileName
         << " opened for reading failed"
         << endl;
         exit (-1);
    }
	
	
    cout << "Begin the transfer from " << fileName
    << " to array"
    << endl;


int i = 0;
char tabkey;

//Transferring rand row 1 and rand row 2 to r[i].1 and r[i].2?
//
while (afile >> r [i].No)
    {
         afile.get (tabkey); // read and throw away
         ++i;
    }
	
afile.close ();
cout << fileName << " closed for the transfer to array" << endl;
return i;

}


void processArray (Number r [], int size)
{
    cout << "Begin the processing of array" << endl;


    for (int i = 0; i < size; i++)
    {
  

		r [i].even = 5;	   	   
        r [i].sum =20;
        r [i].digit = 35;
    }
	
cout << "Array was processed" << endl;

}



void arrayToOutfile (Number r [], int size,
ofstream& outfile, char fileName [])
{
    outfile.open (fileName);
    if (!outfile)
    {
        cout << fileName
        << " opened for array transfer failed"
        << endl;
        exit (-1);
    }
	
cout << "Begin transfer array to outfile" << endl;
outfile << fixed << showpoint << setprecision (4);

//USED FOR PRINTING THINGS THAT APPEARS IN THE OUTPUT FILE
for (int i = 0; i < size; i++)
    {
        outfile << "No\t" << "Type\t" << "Odd\t" << "Even\t" << "Sum\t" << "Digit\t\n" 
        << r [i].No << "\t"
        << r [i].type << "\t"
        << r [i].odd << "\t"
        << r [i].even << "\t"
        << r [i].sum << "\t"
        << r [i].digit
        << endl;
     }
	 
outfile.close ();
cout << fileName << " generated" << endl;
}


Thank you very much in advance :)
Last edited on
Please use code tags when posting code.
1
2
3
//[code]
//like this
//[/ code] (without space between / and code) 
Hello cplusplusgs,

PLEASE ALWAYS USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/
Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

Please give an example of what your files should look like and what your files look like after you run your program.

With no idea of what your files should look like it is going to take me awhile to figure out what the program does.

Andy
Hello cplusplusgs,

What little work I have been able to do so far I found that I can create a text file that looks like:
Numbers 2 24986


But in the function "fileToArray" the while loop is all wrong for reading. You are trying to put "Numbers", a string, into r[i].No, which is an int, and it is not working. When I used this the program worked:

1
2
3
4
5
6
7
8
9
	std::string junk{ "" };
	i = 0;

	while (afile >> junk)
	{
		afile >> junk;
		afile >> r[i].No;
		i++;
	}

Note the i++; o the last line. Otherwise "i" would never change and everything would be put into "r[0]" or whatever value was in "i" at the start of the while loop.

Changing the while loop this way allowed the program to work.

Now the function "arrayToOutfile" needs some work on its formatting to the output file. You may not want to print No Type Odd Even Sum Digit on every other line of the file. As it is things do not line up properly.

Hope that helps,

Andy
What if input on lines 6 and 7 of Andy's code fail? Is it still proper to increment i?
No. Must test every step.
What if file has more data than the r can hold? Must test that too.
1
2
3
4
5
6
std::string junk{ "" };
i = 0;
while ( i < MAX && afile >> junk >> junk >> r[i].No )
{
  ++i;
}

Hello cplusplusgs,

@keskiverto Good point, but I was presenting more of a concept of what could be done. I will keep your solution in mind for the future. You could also say:
while ( i < MAX && afile >> junk >> junk >> r[i++].No ){}

A couple of things I thought of during breakfast.

I forgot to mention to include the header file "<string>".

The line "using namespace std;" is a bad idea, It will get you in trouble some day. Just a matter of when.

Since you have included the header file "<iomanip>" you could make use of "setw()" when you output to the file to format the output better.

Unless you want or need "Numbers 1" etc. in the output file all you really need is the randomly generated number.

Hope that helps,

Andy
Last edited on
You could also say:

There is a critical difference.
If the increment is within the condition expression, then it will happen even when the input fails.
If the increment is in the body, then it will happen only if the input did succeed.
Hello!

Thank you all for the prompt help!


Below is what is should look like for output.txt:


No        Type   Odd Even Sum Digit
1234     Even   2       2    10    4
23467   Odd    2       3     22   5
123       Odd    2      1      6    3


However, I can't get the result. @Handy Andy, may I know why "using namespace std;" will cause problem in future? Just curious as this is what my lecturer taught me all along..to include this in every program we write.

anyway I only wanted
No	Type	Odd	Even	Sum	Digit
to be a header for the program and not for every line, may I know what is your suggestion on doing so?


I've tried this:

1
2
3
4
5
6
7
8
9
std::string junk{ "" };
	i = 0;

	while (afile >> junk)
	{
		afile >> junk;
		afile >> r[i].No;
		i++;
	}

but it still doesn't work. Stating that junk was not declared.
Last edited on
1
2
3
4
5
6
7
8
9
std::string junk{ "" };
	i = 0;

	while (afile >> junk)
	{
		afile >> junk;
		afile >> r[i].No;
		i++;
	}


May I know what does this line actually do?
Stating that junk was not declared.

Brace initialization syntax was introduced in C++11. Do you compile with C++11 support enabled?
Hello cplusplusgs,

"using namespace std;" if for lazy instructors that do not want to have to read "std::" in front of things. As an example: someday you will need to include the header file "<algorithm>" which has a function "sort" in the standard namespace then you will write your own function called "sort". The compiler will first try to use "std::sort()" and if this does not give any errors it will work until you make changes to your "sort" function and can not figure out why the changes do not work.
Search "using namespace std" here and you will find many resuls that address this problem. This link is also worth reading:
http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/

The sample of the output file would be written this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
	//USED FOR PRINTING THINGS THAT APPEARS IN THE OUTPUT FILE
	outfile << "No\t" << "Type\t" << "Odd\t" << "Even\t" << "Sum\t" << "Digit\t\n" << std::endl;

	for (int i = 0; i < size; i++)
	{
			outfile << r[i].No << "\t"
			<< r[i].type << "\t"
			<< r[i].odd << "\t"
			<< r[i].even << "\t"
			<< r[i].sum << "\t"
			<< r[i].digit
			<< endl;
	}

Moving the first line above the for loop will print this as header once. Within the for loop I would use "setw()" before the variable and loose the "\t". The "\t" will not align the columns the way you would want.

1
2
3
4
5
6
7
8
9
        std::string junk{ "" };
	i = 0;

	while (afile >> junk)
	{
		afile >> junk;
		afile >> r[i].No;
		i++;
	}

As I said in a previous message you will need to include the header file "string". It also occurred to me that "fileName" should be defined as a std::string and if your compiles is using C++11 standard or greater "afile.open()" can use a "std::string" in stead of a C string.

Refeering tto the above code:

Line 1 defines the variable "junk". I did this here out of convenience and to keep the code short. Normally I would define this at the beginning of the function.

Line 2 not really needed here. I did this to show that "i" should start at zero and be defined out side the while loop. Later I notice that you did define and initialize "i" earlier. You could leave it here to make sure that "i" will start at zero.

Line 4 will start the while loop reading the string "Numbers" form the file

Line 6 Again reads the second piece of information from the input file that you do not need.

Line 7 Stores the actual random number into the struct as yo want.

Line 8 Increases "i" one, same as i = i + 1;. This allows you to use each element of the array not just the first, element zero. When finished "i" will be the number of records read, so when the value of "i" is used i a for loop condition it will have to be for (...; iterator <= size; ...) because "< size" would leave you one short.

The code was not to show the best way to to this, keskiverto's suggestion is the more accepted way, but to show what needed to be done.

In the end the code will read the file until end of file is reached when the read produces nothing because you are trying to read past EOF. The file stream will fail and so will the while loop.

There are better ways to do the while loop. I was thinking this would be easier to understand.

Hope that helps,

Andy
Last edited on
Topic archived. No new replies allowed.