I want to read the data from my input file
70 95 62 88 90 85 75 79 50 80 82 88 81 93 75 78 62 55 89 94 73 82
and store each value in an array. There's more to this particular problem (the other functions are commented out for now) but this is what's really giving me trouble. I looked for hours at the previous question about data and arrays but I can't find where I'm making the mistake.
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int SIZE = 22;
int grades[SIZE];
void readData() {
int i = 0;
int grades[i];
string inFileName = "grades.txt";
ifstream inFile;
inFile.open(inFileName.c_str());
if (inFile.is_open())
{
for (i = 0; i < SIZE; i++)
{
inFile >> grades[i];
cout << grades[i] << " ";
}
inFile.close(); // CLose input file
}
else { //Error message
cerr << "Can't find input file " << inFileName << endl;
}
}
/*
double getAverage() {
return 0;
}
void printGradesTable() {
}
void printGradesInRow() {
}
void min () {
int pos = 0;
int minimum = grades[pos];
cout << "Minimum " << minimum << " at position " << pos << endl;
}
void max () {
int pos = 0;
int maximum = grades[pos];
cout << "Maximum " << maximum << " at position " << pos << endl;
}
void sort() {
}
*/
int main ()
{
readData();
return 0;
}
and here's my output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Thank you for your time.
The issue is that you're declaring a local grades array with a size of 1, hiding the global grades array. Not only that, you are now accessing the array beyond the bounds, since the local grades array can only hold 1 item.
So get rid of the line:
int grades[i];
However, it needs to be mentioned that this:
int i = 0;
int grades[i];
is not valid C++ syntax. You just stumbled into this by mistake, but that code would not compile if compiled using a strict ANSI C++ compiler.
An array in C++ must be declared using a constant expression to denote the number of entries in the array, not a variable. You, by accident, are using a non-standard compiler extension called Variable Length Arrays or VLA's for short.
If this is for a school assignment, do not declare arrays this way (even if you meant to do it), as it is not officially C++. If you want to declare a dynamic array, that is what std::vector is for.
I don't see any issue in reading the file , you have just confused the global vs local variable of grades
You don't need this
int i = 0;
int grades[];
Inside the function readData
#include <string>
using namespace std;
const int SIZE = 22;
int grades[SIZE];
void readData() {
string inFileName = "grades.txt";
ifstream inFile;
inFile.open(inFileName.c_str());
if (inFile.is_open())
{
for (int i = 0; i < SIZE; i++)
{
inFile >> grades[i];
cout << grades[i] << " ";
}
inFile.close(); // CLose input file
}
else { //Error message
cerr << "Can't find input file " << inFileName << endl;
}
}
int main()
{
readData();
return 0;
}
Your original global array grades, of size 22, is replaced by the local array with the same name but of size 0.
(It is not overwritten, just any code using the variable grades, inside the scope that the second one was defined, will read the value of the second grades array, as it has a higher precedence.)
Both inFile >> grades[i]; and cout << grades[i] << " "; should return runtime errors as you are reading beyond their size (It appears that you are not using a strict compiler).
[int grades[i]; would return a compile time error normally as you shouldn't / usually can't initialize a fixed array with a variable]
I think what is happening, instead of your program crashing, is that grades[i] is just returning an anonymous instance of a variable with value 0, hence your output.
The simplest fix to your problem would be to just delete int grades[i].
(Also delete one of the int i = 0's as you don't need that to be defined twice)
Related
DISCLAIMER: I know it's not practical to use two vectors, but that's our assignment.
Here's my prompt:
In this program, we are going to input the name and score of 100 students from a file named
student.txt. This file has been provided to you. You have to use two vector variables, one to store the
student names, and another to store the student scores. Further, modify the selectionSort function to
sort the student information based on the score in ascending order. Finally, display the sorted student
information on the screen by using cout.
For example, let us assume, the following is the content of the student.txt file (in this case, we have
only 4 value pairs).
Jeff 77
Charles 99
Richard 67
Sina 79
Then, the output of the program would be
Charles 99
Sina 79
Jeff 77
Richard 67
Here's my code:
//Name
//This program will read and sort names and grades from a file using functions and vectors
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
//Function prototype
void selectionSort(vector<int>& vector_values);
int main()
{
ifstream infile;
infile.open("student.txt");
if (infile.fail() == false)
{
vector<string> all_names;
vector<int> all_scores;
string name;
int score;
while (infile >> name >> score) // read one name and one score
{
all_names.push_back(name); // add that name to vector
all_scores.push_back(score); // add that score to vector
int count = 0;
const int max = 1;
selectionSort(all_scores);
while (count < max)
{
count++;
cout << name << " " << score << endl;
}
}
}
else
{
cout << "Could not open the file." << endl;
}
return 0;
}
void selectionSort(vector<int>& vector_values)
{
for (unsigned pass = 0; pass < vector_values.size(); pass++)
{
int minimum = vector_values[pass];
int minimum_index = pass;
for (unsigned index = pass + 1; index < vector_values.size(); index++)
{
if (minimum > vector_values[index])
{
minimum = vector_values[index];
minimum_index = index;
}
}
int temp = vector_values[minimum_index];
vector_values[minimum_index] = vector_values[pass];
vector_values[pass] = temp;
}
}
Here's my problem:
The code compiles just fine and shows the names and their corresponding score, however, it seems that my sorting function is doing absolutely nothing. The names are displaying in the same order they do in the file originally. I have placed the call in every location that I thought it would go, and nothing changed. I am now concerned that the placement of the call isn't the issue, but the entire function.
This statement
cout << name << " " << score << endl;
just prints the two values that you just read. It doesn't matter whether you sorted anything in between.
But you're not sorting the all_names array either. And sorting after adding each item is highly inefficient.
I am sending array of 5 strings into a function that will write them into a binary file. My problem is how can I do that? How can I check the size of array if I am sending it by a pointer? I included #include <string> and using namespace std;.
void my_func(string *array, int n)
{
ofstream my_file("file.bin", ios_base::binary);
if (!my_file)
{
cout << "error" << endl;
return;
}
my_file.write((char*)array, n*sizeof(string));
my_file.close();
}
void fun1()
{
string array[5];
for (int i = 0; i < 5; i++)
{
cout << "enter word " << i + 1 << ": ";
getline(cin, array[i]);
}
my_func(array,5);
return;
}
So this works, but I use too many bytes for nothing, I want to take correct amount of bytes. Or if there is an easy way to do all this, I would be thankful. And please give me a school example, I am a student.
Output:
I overwrite my answer, because first version was written with some misunderstanding
You can simply do it by this way.
void my_func(string *str_array, int n)
{
ofstream my_file("file.bin", ios_base::binary);
if (!my_file.is_open()) {
cout << "error" << endl;
return;
}
for (int i = 0; i < n; i++) {
// If strings are null-terminated use +1 to separate them in file
my_file.write(&str_array[i][0], str_array[i].length() + 1);
// If strings aren't null-terminated write a null symbol after string
// my_file.write("\0", 1);
}
my_file.close();
}
This one of common mistakes of beginners - sizeof(pointer type) expected it returns array size but pointer size will be returned.
I am new to programming, so I have what is probably a basic question. I currently have a text file with 365 lines...one line per day of the year. These are the first four lines of the file:
2003 1 1 18 0 -1 36 50 46
2003 1 2 16 3 -1 43 56 52
2003 1 3 19 7 -1 42 56 49
2003 1 4 14 3 -1 42 58 50
I eventually have to graph these using a special library given to us, but first I want to put the data for each column into an array. This is the part of my code where I attempt to do just that.
#include "library.h"
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
ifstream in;
int yr[364], mo[364], day[364], windSpeed[364], precip[364], snowDepth[364], minTemp[364], maxTemp[364], avgTemp[364];
void main() {
make_window(800, 800);
set_pen_color(color::red);
set_pen_width(8);
// open file, read in data
in.open("PORTLAND-OR.TXT");
if (in.is_open()) {
// read each column into an array
for (int i = 0; i < 364; i++) {
in >> yr[i] >> mo[i] >> day[i] >> windSpeed[i] >> precip[i] >> snowDepth[i] >> minTemp[i] >> maxTemp[i] >> avgTemp[i];
cout << mo[i] << " " << day[i] << endl;
}
in.close();
}
else {
cout << "error reading file" << endl;
exit(1);
}
}
When I attempt to print out all of the values in the second and third columns (month and day), it begins printing from march 8 (3 8) through december 31 (12 31). I need it to print all the way from January 1 to December 31. Is there a reason why the first two months worth of values isn't printing?
Below is a really stupid main-only program that reads your file in with your existing reading code and prints it back out again. I've embedded a running commentary in the code with things you should consider doing.
Basically, this is whaty I was talking about yesterday in loop not displaying all data entries from file
#include <iostream>
#include <fstream>
using namespace std; // bad! Avoid doing this in real life.
int yr[364],
mo[364],
day[364],
windSpeed[364],
precip[364],
snowDepth[364],
minTemp[364],
maxTemp[364],
avgTemp[364]; // bad! define a structure instead
/* Example:
struct stats
{
int yr;
int mo;
int day;
int windSpeed;
int precip;
int snowDepth;
int minTemp;
int maxTemp;
int avgTemp;
};
struct stats statistics[364]; // bad! use a std::vector instead
std::vector<stats> statistics;
*/
int main()
{
// removed all the windowing stuff.
ifstream in;
in.open("PORTLAND-OR.TXT");
if (in.is_open())
{
// read each column into an array
for (int i = 0; i < 364; i++)
{ // what do you do if the file ends early or contains bad information?
in >> yr[i] >>
mo[i] >>
day[i] >>
windSpeed[i] >>
precip[i] >>
snowDepth[i] >>
minTemp[i] >>
maxTemp[i] >>
avgTemp[i];
}
in.close();
}
else
{
cout << "error reading file" << endl;
return 1;
}
// printing out all the stuff that was read
for (int i = 0; i < 364; i++)
{
cout << yr[i] << "," <<
mo[i] << "," <<
day[i] << "," <<
windSpeed[i] << "," <<
precip[i] << "," <<
snowDepth[i] << "," <<
minTemp[i] << "," <<
maxTemp[i] << "," <<
avgTemp[i] << endl;
}
}
The program output Should be:
The numbers are: 101 102 103 104 105 106 107 108 108 110
But my output is:
The numbers are: 0 0 0 0 0 0 0 0 1606416272 32767
This is my code:
// This program reads data from a file into an array.
#include <iostream>
#include <fstream> // To use ifstream
using namespace std;
int main()
{
const int ARRAY_SIZE = 10; // Array size
int numbers[ARRAY_SIZE]; // Array number with 10 elements
int count = 0; // Loop counter variable
ifstream inputFile; // Input file stream object
// Open the file.
inputFile.open("TenNumbers.rtf");
// Read the numbers from the file into the array.
while (count < ARRAY_SIZE && inputFile >> numbers[count]){
count++;
}
// Close the file.
inputFile.close();
// Display the numbers read:
cout << "The numbers are: ";
for (count = 0; count < ARRAY_SIZE; count++){
cout << numbers[count] << " ";
}
cout << endl;
return 0;
}
This is the contents of the TenNumbers.rtf file I'm reading the data from:
101
102
103
104
105
106
107
108
109
110
UPDATE 1:
I tried using txt file but the results are similar.
The numbers are: 0 0 0 0 0 0 0 0 1573448712 32767
UPDATE 2:
I found where the issue was. After running if (inputFile.good()) I found out the file was not getting opened.
Hi I have compiled your code, with the .txt it runs well, without gives the strage numbers that you see.
So probably you are opening a file that does not exists, or can not be red.
// This program reads data from a file into an array.
#include <iostream>
#include <fstream> // To use ifstream
#include <vector>
using namespace std;
int main()
{
std::vector<int> numbers;
ifstream inputFile("c.txt"); // Input file stream object
// Check if exists and then open the file.
if (inputFile.good()) {
// Push items into a vector
int current_number = 0;
while (inputFile >> current_number){
numbers.push_back(current_number);
}
// Close the file.
inputFile.close();
// Display the numbers read:
cout << "The numbers are: ";
for (int count = 0; count < numbers.size(); count++){
cout << numbers[count] << " ";
}
cout << endl;
}else {
cout << "Error!";
_exit(0);
}
return 0;
}
This snippet checks if the file exists, raises an error if not, and uses a vector(more suitable in c++)
Your file name has rtf as suffix. Does it contain any RTF info in it?
The error that I see in your code is that you are assuming ARRAY_SIZE number of ints were successfully read when you are printing the numbers.
Use:
// Display the numbers read:
cout << "Number of ints read: " << count << std::endl;
cout << "The numbers are: ";
for (int i = 0; i < count; i++){
cout << numbers[i] << " ";
}
This will, most likely, reveal any problems in reading the data.
ARRAY_SIZE is the number of ints you allocated in the array; that is, it is the max number of ints.
count is the actual number of ints read from the file. So your final loop should go up to count since that is the number of actual data. So the loop that prints your data should be:
int i;
for (i = 0; i < count; ++i)
cout << numbers[count] << " ";
Or you can walk a pointer:
int *start;
for (start = numbers; (numbers - start) < count; ++numbers)
cout << *numbers << " ";
Also, I think the file extension should be "txt" rather than "rtf", but that doesn't make a difference.
An RTF file is not just plain text (it's surrounded by markup) and the character encoding may differ, thus resulting in wrong interpretation of the numbers.
So, in your reading loop:
// Read the numbers from the file into the array.
while (count < ARRAY_SIZE && inputFile >> numbers[count]){
count++;
}
the input stream inputFile by default is skipping white spaces which in your case could be encoded differently, thereby skipped or messed up in some way.
Note: Try and add a test line that prints the read number before you store it in the array.
I had met this problem before too. I copy the content into a new file and save as different name. Then it will be fine when run it again.
I'm a beginning C++ student and am having difficulty in getting my code to read multiple integers from a text file.
My task is to take pre existing code (the code I posted below) and modify it so instead of taking a user's input, it reads from a text file.
The main issue i'm having lies in the void getNumber function. It originally was just a simple cin statement that read 20 numbers input by the user, carried them into the main function, processed them in another function, then prints the results in the last one.
I have modified the code to read the text file successfully, however, it only reads the first value of the text file (ex text file reads: 1 2 3 4 ... 20) and the output reads: 1 1 1 1 1...
I've been looking up solutions for hours, unfortunately, a lot of the responses call for things I am not familiar with. It seems I will need to establish some type of loop? I'm unsure.
Thank you!
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
const int N = 20;
//Function prototypes
void initialize(int& zeroCount, int& oddCount, int& evenCount);
void getNumber(int& num);
void classifyNumber(int num, int& zeroCount, int& oddCount,
int& evenCount);
void printResults(int zeroCount, int oddCount, int evenCount);
int main ()
{
//Variable declaration
int counter; //loop control variable
int number; //variable to store the new number
int zeros; //variable to store the number of zeros
int odds; //variable to store the number of odd integers
int evens; //variable to store the number of even integers
initialize(zeros, odds, evens); //Step 1
cout << "Please enter " << N << " integers."
<< endl; //Step 2
cout << "The numbers you entered are: "
<< endl;
for (counter = 1; counter <= N; counter++) //Step 3
{
getNumber(number); //Step 3a
cout << number << " "; //Step 3b
classifyNumber(number, zeros, odds, evens); //Step 3c
}// end for loop
cout << endl;
printResults(zeros, odds, evens); //Step 4
return 0;
}
void initialize(int& zeroCount, int& oddCount, int& evenCount)
{
zeroCount = 0;
oddCount = 0;
evenCount = 0;
}
void getNumber(int& num)
{
ifstream inData;
inData.open("inputfile.txt");
inData >> num;
}
void classifyNumber(int num, int& zeroCount, int& oddCount,
int& evenCount)
{
switch (num % 2)
{
case 0:
evenCount++;
if (num == 0)
zeroCount++;
break;
case 1:
case -1:
oddCount++;
} //end switch
} //end classifyNumber
void printResults(int zeroCount, int oddCount, int evenCount)
{
ofstream outData;
outData.open("outputfile.txt.");
outData << "There are " << evenCount << " evens, "
<< "which includes " << zeroCount << " zeros"
<< endl;
outData << "The number of odd numbers is: " << oddCount
<< endl;
outData.close();
} //end printResults
The problem is that in the getNumber function you open the file every time it's called. That makes it start the reading from the beginning every time.
What happens is that you open the file every time inside of the getNumber function.
In doing so, you always start reading the file from the beginning. What you'd want to do is to read each time the next integer and not the same one. To do this you could open the file from the main function and pass the ifstream to the getNumber function.
int main ()
{
...
ifstream inpStream;
inpStream.open("inputfile.txt");
for (counter = 1; counter <= N; counter++) //Step 3
{
getNumber(number, inpStream); //Step 3a
cout << number << " "; //Step 3b
classifyNumber(number, zeros, odds, evens); //Step 3c
}// end for loop
return 0;
}
void getNumber(int& num, istream& inpStream)
{
inpStream >> num;
}
Notice that this way you can define inpStream to be cin and it will work too. That is because the getNumber function gets a reference to an istream (which cin is).