Loop to open a file, and check it until the right name inserted

Hi! I'm a beginner and have an assignment at school. And obviously I have a mistake somewhere, and I can not see where=) I tried to rewrite everything from the beginning, but it still doesn't go for me. Please if you see anything I can improve tell me.

The task I stuck in is to write a loop that would prompt the user to name a file to open, check if it is correct otherwise asks to insert it again until succeed. When I am trying a while loop, it does not let me enter correct info, if I entered it incorrectly. If loop does not go more than once.

Another question is: I need to display all info in separate function but whenever I am getting it program stops.

I tried to insert this function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*************************************
The printReport function is displays all
report to user : sorted data, average
and mode.
*************************************/
void printReport( vector<double> numb, double average, double median, double mode)
{
    cout << "************************************************"<<endl;
    cout << " Sorted scores are: " << endl;

    showOrder ( numb );

    cout << "The Average is: " << setprecision(1) << fixed << average << endl;

    cout << "The Median is: " << setprecision(1) << fixed << median << endl;

    cout << "The Mode is: " << mode << endl;
}


Assignment

Write a program that reads a text file containing a set of test scores, calculates the average, median and mode. The file name must be entered by the user. Your program should follow these steps:

1. Ask the user for the file name
2. Read the file name and use it to open the file
3. Check if the file opening was successful. If not, ask the user to enter it again until you succeed.
4. Read all scores to a vector.
5. Sort the data (you will need this for the median)
6. Calculate the average, median and mode
7. Print on the screen:
The scores sorted from least to greatest
The average (rounded to one-decimal place), median(rounded to one-decimal place) and mode


That is what i have so far:

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
175
176
177
178
179
180
181
182
183
184
  
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <iomanip>
#include <algorithm>

using namespace std;

//Function Prototypes:
vector<double> readData();
double calculateAverage (vector<double> , int);
double calculateMedian(vector<double>, int);
double calculateMode(vector<double>, int);
void showOrder ( vector<double>);


int main()
{
    double average, median, mode;
    int vSize;

 	vector<double> numbers(readData());

 	vSize = numbers.size();

    cout << " Sorted scores are: " << endl;

    showOrder ( numbers );

    average = calculateAverage(numbers, vSize);

    cout <<"\nAverage score: "<< setprecision(1) << fixed << average << endl;

    median = calculateMedian( numbers, vSize );

    cout<< "Median score: "<< setprecision(1) << fixed << median<< endl;

    mode = calculateMode(numbers, vSize);

    cout<< "Mode score: "<< setprecision(1) << fixed << mode<<endl;



    return 0;
}

/*************************************
The readData Function reads the file
name, use it to open the file, check
if it is correct name of file. Returns
    a vector with data from the file
*************************************/
vector <double> readData()
{
   //Ask the user for the file name


	vector<double> vecData;
	double value;

	//Ask the user for the file name

	string fileName;
    ifstream inFile;

    cout << "Enter File Name : ";
	getline( cin, fileName );

    inFile.open(fileName.c_str());  
   
    if (!inFile) // Check if could not open the file 
    {
        cout << "Error opening " << fileName << " for reading!\n";

    }
    else
        {
            
            while ( inFile >> value )
            {
                 vecData.push_back(value);
            }
        inFile.close();
        }

        sort(vecData.begin(), vecData.end());

     return vecData;
}


/*************************************
The calculateAverage function adds all
numbers of a vector and divide amount
by the number of points. returns rounded
by one decimal place.
*************************************/
double calculateAverage( vector<double> vect, int sz)
{
    double total = 0;
    double average;
  for (int i = 0; i < sz; i++)
        total += vect[i];
  average= total/sz;

  return average;
}


/*************************************
The calculateMedian function receives
sorted vectors and determines the middle
point. If odd number of points - one
median point, if even number than it
returns average of two middle points.
*************************************/

double calculateMedian( vector<double> sorted, int vecSize)
{
    double med;
    int m;
    m = vecSize/2;

    if ( vecSize % 2 == 0)
    {
        med = (sorted[m - 1]+ sorted[m + 1])/2;
    }
    else
    {
      med = sorted[m];
    }

    return med;
}


/*************************************
The calculateMode function accepts data
vector and size of it as arguments. The
function goes through all data and
returns the data point that is repeated
more often. If more than one occur returns
only one of it and ignore the rest.
*************************************/
double calculateMode (vector<double> num,int vecSize)
{
    double number = num[0];
    double mode = number;
    int index = 1;
    int indexMode = 1;


    for (int i=1; i<vecSize; i++)
{
      if (num[i] == number) //count how many times the data point occurs
        {
            index++;
        }
      else // check another  data point
        {
            if (index > indexMode)
                {
                  indexMode = index; //count the most often occurring number
                  mode = number;
                }
           index = 1;
           number = num[i];
        }
}

    return mode;
}


void showOrder ( vector<double> num)
{
  for  (int index = 0;index < num.size(); index++)
  {
      cout << num[index]<< " ";
  }
}
Last edited on
The problem is at step 2:
2. Read the file name and use it to open the file


Your code in function readData() does this:
2. Read the file name


but nowhere is there any code which does this:
2. ................. and use it to open the file
I guess I know what you mean, but not quite sure how to fix it.. Are you talking about this line 71?
 
inFile.open(fileName.c_str());
Last edited on
i would use a loop like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
using namespace std;

int main()
{
    string name="";
    cin>>name;
    while(true)
    {
        if(name=="bird1234")
        {
            cout<<"Welcome" <<name;
            break;
        }
        else
        {
            cout<<"\nTry Again\n";
            cin>>name;
        }
    }
    return 0;
}


Output

hello

Try Again
cpluscplus

Try Again
bird1234
Welcomebird1234 




Ok, it looks like you made a number of changes to the code there (generally it's preferable to post the updated code in a new post, rather than editing the original post - it makes it easier to keep track of what changes have been made).

Yes,
 
    inFile.open(fileName.c_str());
was missing.

Now The problem is at step 3:
3. Check if the file opening was successful. If not, ask the user to enter it again until you succeed.


Here, you've done this part:
3. Check if the file opening was successful.


but have deleted the code for this part:
3. If not, ask the user to enter it again until you succeed.


The original code (as far as I can remember it) was closer to what you need.

You need to do this.
ask for file name
try to open the file

while (file is not open)
    ask for file name
    reset error flags of file stream
    try to open the file


this line: "reset error flags of file stream" translates to inFile.clear();
Last edited on
Eah, sorry for confusion! it is an update. The original code was:
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <algorithm>

using namespace std;

//Function Prototypes:
vector<double> readData();
double calculateAverage (vector<double>, int);
double calculateMedian(vector<double>, int);
double calculateMode(vector<double>, int);
void showOrder ( vector<double>);
void printReport( vector<double>, double, double, double);


int main()
{
    double average, median, mode;
    int vSize;

 	vector<double> numbers(readData());

 	vSize = numbers.size();

	average = calculateAverage(numbers, vSize);

	sort(numbers.begin(), numbers.end());

	median = calculateMedian( numbers, vSize );

	mode = calculateMode(numbers, vSize);

    printReport(numbers, average, median, mode);

    return 0;
}

/*************************************
This Function reads the file name, use
it to open the file, check if it is
correct name of file. Returns a vector
with data from the file
*************************************/
vector <double> readData()
{
   //Ask the user for the file name
	char cInput;
	ifstream inFile;
	string fileName;
	vector<double> vecData;

	cout << "Please enter the file name : ";
	getline(cin, fileName);

	while (inFile.fail()) //Check for mistakes in opening file
	{
		cout << "Error! Please enter the file name: ";
		cin >> fileName;
	}

    //If the file opened successfully, process it
    if (inFile)
        {
            double value;

            // reads data to a vector
            while ( inFile >> value )
            {
                vecData.push_back(value);
            }
        }

     return vecData;
}


/*************************************
This function adds all numbers of a vector
and divide amount by the number of points.
returns rounded by one decimal place.
*************************************/
double calculateAverage( vector<double> vect, int sz)
{
    double total = 0;
    double average;
  for (int i = 0; i < sz; i++)
        total += vect[i];
  average= total/sz;

  return average;
}

/*************************************
This function receives sorted vectors
and determines the middle point. If
odd number of points - one median point,
if even number than it returns average
of two middle points.
*************************************/
double calculateMedian( vector<double> sorted, int vecSize)
{
    double med;
    int m;
    m = vecSize/2;

    if ( vecSize % 2 == 0)
    {
        med = (sorted[m - 1]+ sorted[m + 1])/2;
    }
    else
        med = sorted[m];

    return med;
}

/*************************************
The calculateMode function accepts data vector and size of it as arguments. The function goes thru all data and returns the data point
that is repeated more often. If more
than one occur returns only one of it
and ignore the rest.
*************************************/
double calculateMode (vector<double> num,int vecSize)
{
    double number = num[0];
    double mode = number;
    int index = 1;
    int indexMode = 1;


    for (int i=1; i<vecSize; i++)
{
      if (num[i] == number) //count how many times the data point occurs
        {
            index++;
        }
      else // check another  data point
        {
            if (index > indexMode)
                {
                  indexMode = index; //count the most often occurring number
                  mode = number;
                }
           index = 1;
           number = num[i];
        }
}

    return mode;
}

/******************************************
The showOrder function  accepts numbers in
the vector as arguments. The function displays
sorted list of data
******************************************/

void showOrder ( vector<double> num)
{
  for  (int index = 0;index < num.size(); index++)
  {
      cout << num[index]<< " ";
  }
  cout << endl;
}

/*************************************
The printReport function is displays all
report to user : sorted data, average
and mode.
*************************************/
void printReport( vector<double> numb, double average, double median, double mode)
{

    cout << " Sorted scores are: " << endl;

    showOrder ( numb );

    cout << "The Average is: " << setprecision(2) << fixed << average << endl;

    cout << "The Median is: " << setprecision(2) << fixed << median << endl;

    cout << "The Mode is: " << mode << endl;
}




I combined the original and updated and got

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
vector<double> vecData;
	double value;

	//Ask the user for the file name

	string fileName;
    ifstream inFile;

    cout << "Enter File Name : ";
	getline( cin, fileName );

    inFile.open(fileName.c_str());

    while (inFile.fail()) //Check for mistakes in opening file
	{
		cout << "Error! Please enter the file name: ";
		cin >> fileName;
	}

    //If the file opened successfully, process it
    if (inFile)
        {
            // reads data to a vector
            while ( inFile >> value )
            {
                vecData.push_back(value);
            }
        }


The problem now it is that if first input was wrong, and after that input is correct it does not accept it.

Thank you for Help! I feel like I am very close to the answer, just need to play with it a little probably
Last edited on
Thanks for the update - I think I made you work a little too hard there.

Still, there's no need to just play with the code, follow a specific plan. I gave some pseudo-code previously:

You need to do this:
ask for file name
try to open the file

while (file is not open)
{
    ask for file name
    reset error flags of file stream
    try to open the file
}


Your version instead has just:
ask for file name
try to open the file

while (file is not open)
{
    ask for file name
}
Last edited on
You are so right! That was exactly what I missed. Now it works) Thank you a lot!

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
cout << "Enter File Name : ";
	getline( cin, fileName );

    inFile.open(fileName.c_str());

    while (inFile.fail()) //Check for mistakes in opening file
	{
		cout << "Error! Please enter the file name: ";
		cin >> fileName;
		 inFile.clear();
		 inFile.open(fileName.c_str());
	}

    //If the file opened successfully, process it
    if (inFile)
        {
            // reads data to a vector
            while ( inFile >> value )
            {
                vecData.push_back(value);
            }
        }

        sort(vecData.begin(), vecData.end());

        inFile.close();
Topic archived. No new replies allowed.