Why is this file not reading into my array? - c++

Can anyone tell me why my array is not filling up with the info I am trying to get from my data file? When I output the array it just gives me garbage. Thanks in advance.
#include <iostream>
#include <fstream>
using namespace std;
// function main begins program execution
int main()
{
/* input correct answers file */
const int ARRAY_SIZE = 20; // Array size
int correctAnswers[ARRAY_SIZE]; // Array to hold correct answers
int count = 0; // Loop counter variable
ifstream inputFile; // Input file stream object
// open the file
inputFile.open("c:\\correctanswers.txt");
// read the numbers from the file into the array
while (count < ARRAY_SIZE)
{
inputFile >> correctAnswers[count];
count++;
}
// close the file
inputFile.close();
// display the correct answers
cout << "The correct answers are: ";
for (int index = 0; index < count; index++)
cout << correctAnswers[index] << " ";
cout << endl;
system ("pause");
return 0;
}

You never check to see if the stream is ever initialized to the desired state. I would begin by checking whether the stream is able open the given argument: if(inputFile.is_open)

correctAnswers is an array of int, you are trying to copy onto it strings coming from the file. I suggest you to use an auxiliary variable to store the line grabbed from the file, then manipulate it as you want. Also, you probably want to make sure not to exceed the end of file limits...

Related

trying to read data file, store in array and print all the elements but it isnt working

not sure what i'm doing wrong but this is my code
int main (){
int marks [100];
int i=0;
ifstream inputfile;
ofstream outputfile;
inputfile.open("data.txt");
if(!inputfile.is_open())
{
cout<< "File did not open"<< endl;
return 0;
}
cout<<"Marks in File:"<<endl;
while (marks [i] != -1)
{
inputfile>>marks[i];
cout << marks[i] <<endl;
i++;
}
return 0;
}
the output is messed up and returns stuff that was never in the data file to begin with
Here is the minimal code for reading data from a file and write it to console. Description is added as comments
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
ifstream configrecord("D:\\Temp\\temp.txt"); // opening the file named temp for reading.
if(configrecord.good()) // check whether the file is opened properly.
{
string line;
while (getline(configrecord, line)) // reading a line from file to std::string
{
cout << line; // printing the line, if you want it to store in an array, you can use the std::string::data() api to get the character pointer.
}
configrecord.close(); // closing the file after reading completed
}
}
If we translate your code to English, we get:
Check if the current array element is -1, if it is, break the loop.
Read the value into the current array element.
Output the value.
Move to the next array element and repeat.
Notice a big problem: We're checking if the value is -1 before we actually read it. We need to reverse the order of steps 1 and 2 so that we get:
Read the value into the current array element.
Check if the current array element is -1, if it is, break the loop.
Output the value.
Move to the next array element and repeat.
We can do this by using true as our loop condition and then using an if statement to check if the inputted value is -1 later in the loop, using break to break the loop if it is.
#include <fstream>
#include <iostream>
//using namespace std; is considered bad practice
int main()
{
std::ifstream inFile("input.txt");
int marks[100];
//check if file is open stuff...
for(int i = 0; true; i++)
{
inFile >> marks[i];
if(marks[i] == -1) break;
std::cout << marks[i] << '\n'; //endl flushes the buffer, unnecessary here.
}
}
Of Note: it is good practice that if you use an if statement, you also include an else statement. Also, your while loop is confusing, because it stops if it encounters negative one, so I am assuming you know that integer -1 is not in the file.
int n = -1;
if(!inputfile.is_open())
{
cout<< "File did not open"<< endl;
}
else
{
cout<<"Marks in File:"<< endl;
while(!inputfile.eof()){ // .eof is bad practice, but for this instance it works.
File >> marks[n];
n++; // Essentially the size of the array (Number of values), keeping track of how many values there are will assist you in the output process.
}
}
When you are done reading the file, you should close it and then use the data in the array.
inputfile.close();
Lastly, in order to output an array of data, you must use a for loop or some type of iterator to access the values stored in the array.
for(int i=0; i < n ; i++) // Output array. Where array size is less than n.
{
cout << marks[i] << " "; // " " inputs a space in between each word.
}

Printing integers from a file using an array

I'm just beginning to learn C++ and I am having some trouble with a program. It's supposed to sort numbers from an external file. I've managed to successfully code the sorting algorithm, but I am having trouble working with the external file. I am just testing some things out in a separate program to gain an understanding of how things like ifstream work. I should be able to figure out how to implement it into my program once I gain a better understanding of how it works.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
using namespace std;
int count;
ifstream InFile;
InFile.open ("unsorted.txt");
InFile >> count;
int numbers[count];
for(int a = 0; a < count; a++)
InFile >> numbers[a];
cout << numbers << endl;
}
Currently, the output for this is 0x7ffc246c98e0 I am not sure why this is the case I'm just attempting to print my file of integers. Could anyone help explain what I am doing wrong? I'd be very thankful.
When you do
cout << numbers << endl;
you print the pointer to the first element of the array.
You want
cout << numbers[a] << '\n';
to print the current element.
Furthermore, if that's all your program is doing, then you don't actually need the array. All you need is a single int variable:
int value;
for (int a = 0; a < count; ++a)
{
InFile >> value;
cout << value << '\n';
}
That also solve the problem with the variable-length array (since there isn't any).
If you intend to use count variable to count the file size or something, it is where your code goes wrong. You can't count the length of the file as like as you are trying.
while( getline ( InFile, line ) )
{
count += line.length();
}
Maybe, try like this!!!
If you use
InFile>>count;
it would try to store all the string from InFile stream to count, which is not intended.

Positioning in arrays, fstream, and char comparison

I am currently trying to do an assignment in my C++ class. I think I've gotten as far as I can on my own.
The assignment calls for me to read names from a text file, put the names in order, and write them to a new file.
The names in the given text file are formatted as follows:
Jackie Sam Tom Bill Mary Paul Zev Barb John
My code that I have for the assignment:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string nameArray[26] = {};
int main() {
// Defined variables
int y = 65, lineNumber = 0;
string readName;
// Opens the text file LineUp
ifstream readfile;
readfile.open("LineUp.txt");
// Opens the text file InOrder
ofstream outfile;
outfile.open("InOrder.txt");
// Read name from file
while (readfile >> readName) {
// If first character of name != char(y),
// run loop
while (readName[0] != char(y)) {
y++;
lineNumber++;
// If first character of name = char(y),
// add name to lineNumber's position in array
if (readName[0] == char(y)) {
nameArray[lineNumber] = readName;
}
}
// Reset values of lineNumber and y
y = 65;
lineNumber = 0;
}
// Writes names in array to file
for (int x = 0; x <= 25; x++)
outfile << nameArray[x] << endl;
// Close files
readfile.close();
outfile.close();
// Print statement so you can see at least
// something happens
cout << "KIDS ORGANIZED. BEEP. BOOP. BEEP.\n";
cin.get();
return 0;
}
The output to the file made in the program that holds the ordered names:
Barb
John
Mary
Paul
Sam
Tom
Zev
(It contains many more empty lines than what stack overflow shows.)
The questions I have are as follows:
1: How can I get rid of the empty spaces in the array for when I want to write the names to the text file InOrder.txt?
2: The names Jackie and Bill are not being shows because the positions in the array are being overwritten by the other two names. How can I check if those positions are filled to add in these two names?
3: Is there anything in my program I can do to make it more efficient or more readable? Or just do better in general, I guess.
A big thank you to anyone willing to try to figure out how to solve these problems!
One problem is the length of your string array. You only reserve 26 elements. In your for loop
for (int x = 0; x <= 26; x++)
outfile << nameArray[x] << endl;
you try to access element 0 to 26 (that are 27 elements in total), that's more than you allocated. You have to change this loop to something like
for (int x = 0; x < 26; x++)
outfile << nameArray[x] << endl;
so it won't crash.
But the main problem in your program is the sorting system. As you already have noticed, as soon as two kids have a name with the same first letter, one name will be overwritten.
A better approach would be to use some of the standard libraries.
First i would not use a std::string array, but a std::vector. A vector is, simply said, a better and dynamic array with a lot more functions. If you want to know more about vectors, check here.
With a vector you can read every name first and sort it later:
std::vector<std::string> nameVector;
while(readfile >> readName) {
//add name to the end of the vector
nameVector.push_back(readName);
}
Now you can use std::sort() to sort the vector.
std::sort(nameVector.begin(), nameVector.end());
And last write everything to your output file:
for(int x = 0; x < nameVector.size(); ++x)
outfile << nameVector[x] << std::endl;
Firstly don't use the nameArray[26] in the for-loop as it is out of range.
Secondly by now surely you must have realized the issue. You logic reserve a place for name with each alhpabet and if there are two names starting with same alphabet it creates problem. Also the blank spaces are ther because of the places in the array not having any names starting with respective alphabet. for example. no name starts with A so a blank space will be in start of the file similary no name starts with C so a blank space would be there after the name Barb.
As per your logic the solution should be something like this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//Can be many names
string nameArray[100] = {};
int main() {
// Defined variables
int y = 65, lineNumber = 0;
string readName;
// Opens the text file LineUp
ifstream readfile;
readfile.open("LineUp.txt");
// Opens the text file InOrder
ofstream outfile;
outfile.open("InOrder.txt");
//Run while the names are not checked for all alphabets
while (y <= 90) {
// Read names from file till the end is reached
while (readfile >> readName) {
// If first character of name != char(y),
// run loop
if(readName[0] == char(y)) {
// If first character of name = char(y),
// add name to lineNumber's position in array
nameArray[lineNumber] = readName;
lineNumber++;
}
}
}
//Check File for next character
y++;
}
// Writes names in array to file
for (int x = 0; x < lineNumber; x++)
outfile << nameArray[x] << endl;
// Close files
readfile.close();
outfile.close();
// Print statement so you can see at least
// something happens
cout << "KIDS ORGANIZED. BEEP. BOOP. BEEP.\n";
cin.get();
return 0;
}
Note that this code works for only Upper-case letters and sorts only based on first alphabet.

Why is the next line not executing C++

I have attached my full source code of my program that can open a .txt file. It doesn't execute after the cout << length. I am trying to store the .txt file information in memory by using an array.
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;
char filename[128];
char file[10][250];
int count;
int length;
string line;
int main ()
{
int count = 0;
int length = 0;
cout << "Filename: ";
cin.clear();
cin.getline(filename, sizeof(filename));
string new_inputfile(filename);
ifstream inputfiles (new_inputfile.c_str());
if(!inputfiles.is_open())
{
cout << "File could not be opened. \n ";
}
else
{
for (int i=0; getline(inputfiles,line); i++)
{
length++;
}
cout << length;
// char file[length][250]; <- How can I create the array based on the length variable?
// CODE DOES NOT EXECUTE AFTER THIS.
while(!inputfiles.eof() && (count<10))
{
inputfiles.getline(file[count],250);
count++;
}
for(int i=0; i < count; i++)
{
cout << file[i] << endl;
}
}
inputfiles.close();
return 0;
}
Also, since file[] is char, say for example file[1] contained the char Name=Mike, how do I strip off everything before the =. I want just Mike. I know with string, I can use substr() method, but I don't know for char.
This is horribly wasteful way to count number of lines in a file.
for (int i=0; getline(inputfiles,line); i++) // i is also completely useless here
{
length++;
}
You're reading the whole file only to throw everything away and start again! And after this loop is done, inputfiles.eof() will be true and you'll never enter neither the next while loop nor the last for loop (because i == count). Execution skips directly to inputfiles.close() and then you return from main.
I suggest you work on the line string as you go:
for ( ; getline(inputfiles, line); )
{
// do stuff with line and ditch the global char arrays
}
If you want store the lines for later, well, just save them :) The easiest thing to do is to use a vector:
std::vector<std::string> all_them_lines;
while (getline(file, line) all_them_lines.emplace_back(line);
There, the entire file is now saved in all_them_lines, line by line. You can access them just like you would in an array, like all_them_lines[0]. You also don't need to know the number of lines beforehand - vectors expand automatically when you add stuff to them.
Now to parse a line and extract formatted input from it, check out what stringstream class has to offer.
You asked:
// char file[length][250]; <- How can I create the array based on the length variable?
Declare file as:
char (*file)[250] = NULL;
and then,
file = new char[length][250];
Make sure you call delete [] file before the end of the function.
You said:
// CODE DOES NOT EXECUTE AFTER THIS.
You can rewind the stream and start reading from it again.
inputfiles.seekg(0);
count = 0;
while(!inputfiles.eof())
{
inputfiles.getline(file[count],250);
count++;
}

How to read a txt file with characters (without spacing) and store into a 2D character array with 15x15 in visual c++?

I'm kind of a newbie in C++ programming.. My command prompt output is a big bulk (repeated) of the characters I have in my txt file. I create a 2d array map[15][15] and try to read the txt file. the reading part is ok but now I dunno how to put them in a 2D character array..
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
char map[15][15];
int alp = 0;
int i = 0;
int main()
{
ifstream in;
//string s;
in.open("city.txt");
if(!in.is_open())
{
cout << "File open error! " << endl;
}
else
{
while(!in.eof())
{
//getline(in, s);
in >> map[i];
i++;
alp++;
//if(in.eof()) break;
cout << map[i] << endl;
}
}
for(i = 0; i <= alp; i++)
{
cout << map[i];
}
in.close();
return 0;
}
eof() will only return true only after the first failed read operation. That operation will not be caught by your code. You could have a test for eof directly after the read and then break if eof(), but that's not elegant:
IO operations on streams return a ref to the given stream. Streams have a meaningful conversion to bool. True indicates that the read was successful, e.g. eof wasn't reached yet, and the read target contains a new correct input value. The idiomatic way of using this feature is "while(in >> map[i])".
As to the algorithm: You say that there are no spaces and I assume it's all ascii chars, so it boils down to double looping over the array's lines and columns with two for loops. Inside those loops would be a line reading each character explicitly with get() like
if(!cin.get(map[i][j])) {/* unexpected eof/io error, abort or whatever */ }
As the data is textual, and separated into lines, I suggest you read directly into the sub-array using e.g. std:istream::getline:
for (size_t i = 0; in.getline(map[i], 15); ++i)
;