This is the program that needs to write a code to read data from file. The file looks like:
1234 200.55
5678 1234.56
9876 2.33
I need to store the first number as the account number and the second one as the balance of the account.
#include<iostream>
#include<fstream>
using namespace std;
const int MAX_NUM=100;
int read_accts(int acctnum[], double balance[], int max_accts);
int main()
{
int acctnum[MAX_NUM];
double balance[MAX_NUM];
int max_accts=0;
int num_accts;
num_accts = read_accts(acctnum,balance,max_accts);
return 0;
}
int read_accts(int acctnum[],double balance[],int max_accts)
{
ifstream infile;
infile.open("information");
while (infile >> acctnum[max_accts] && max_accts < MAX_NUM)
{
infile >> balance[max_accts];
max_accts++;
}
for (int i=0; i<=max_accts; i++)
{
cout << acctnum[i]<<endl;
cout << balance[i]<<endl;
}
infile.close();
return max_accts;
}
The output of this program is
0
0
It should be same as the text file has. it shouldn't be 0 and 0.
Thanks in advance Any help is appreciated.
First of all, you're printing one too many elements in each array. The printing loop should run from 0 to max_accts (not including), like so:
for (int i=0; i < max_accts; i++)
Now, since you're attempting to read a file named "information", I've created such file with the contents described in your question and ran your code. The output I get is:
1234
200.55
5678
1234.56
9876
2.33
This looks like what you wanted to get (and not zeroes), so your code seems to be working alright. Perhaps you're not opening the right file?
Either correct the name of the file from "information" to something else, or make sure you have a file named "information" in the current working directory.
For the file part of you program, the code below would be a better version of your function. It uses end of file and has the ability to handle of the file doesn't exits
int read_accts(int acctnum[], double balance[], int max_accts)
{
ifstream infile;
infile.open("information");
if (!infile)//check if file exists
{
//add code to handle missing file here
}
while (!infile.eof())
{
infile >> acctnum[max_accts];
infile >> balance[max_accts];
max_accts++;
}
infile.close();
return max_accts;
}
How about using the old school stdio API for a simple task like that?:
int accounts[3], i;
float balance[3];
FILE *fp = fopen("file.txt", "r");
for (i = 0; i < 3; i++)
fscanf(fp, "%d %f", &account[i], &balance[i]);
fclose(fp);
Related
I am trying to write a console application that reads from file in the form (all are integers)
Example:
c
k
a1 a2 a3
a4 a5 a6
a7 a8 a9
where first line is for number of rows and second for number of columns and c, k and an, all are integers.
if I cout<<row or column it puts the program into loop.
I’ve tried reading the whole line with
getline(my file, line)
and then
row=stoi(line);
but to no avail.
EXAMPLE CODE
void read_row_and_column_function(int* fucntion_selector,string* ptr_to_name_of_file)
{
int row, column;
ifstream myfile;
myfile.open(*ptr_to_name_of_file);
if(myfile.is_open())
{
myfile>>row;
myfile>>column;
myfile.close();
}
cout<<row;
}
Expected result is row.
EDIT FOR FULL CODE
#include<iostream>
#include<fstream>
using namespace std;
void file_name_getter();
void read_ploynomials_and_variables_function(int* fucntion_selector,string* ptr_to_name_of_file)
{
int polynomials, variables;
ifstream myfile;
myfile.open(*ptr_to_name_of_file);
if(myfile.is_open())
{
myfile>>polynomials;
myfile>>variables;
myfile.close();
}
cout<<polynomials<<endl;
}
void data_structure_seletor(string* ptr_to_name_of_file)
{
cout<<"Select the desired data structure to store polynomials\n1. Matrix\n2. Linked List\n3. Change file name\n0. EXIT\nINPUT: ";
int data_structure_choice;
cin>>data_structure_choice;
while(1)
{
if (data_structure_choice==1)
{
read_ploynomials_and_variables_function(&data_structure_choice, ptr_to_name_of_file);
}
else if (data_structure_choice==2)
{
read_ploynomials_and_variables_function(&data_structure_choice, ptr_to_name_of_file);
}
else if (data_structure_choice==3)
{
cout<<"\n";
file_name_getter();
}
else if (data_structure_choice==0)
{
return;
}
else
{
cout<<"\nIncorrect option. TRY AGAIN!!\n\n";
}
}
}
void file_name_getter()
{
string name_of_file, extension=".txt";
cout<<"Enter name of the file you want to open\nNOTE: \".txt\" extension will be appended by the program\nNAME of file: ";
cin>>name_of_file;
name_of_file=name_of_file+extension;
data_structure_seletor(&name_of_file);
}
int main()
{
file_name_getter();
return 0;
}
The files are in the same folder. Example file name 10x5, 3x3 etc
EDIT
__The query is solved now. Problem was in void data_structure_selector() in while(1) loop.
You read data_structure_choice only once outside the loop. And don't modify it's value inside the loop. Did you mean, to read the input inside the loop?
You could use the part also as the loop-condition to loop until eof is reached or a value was entered, that can't be parsed as int:
int data_structure_choice;
while(cin>>data_structure_choice) {
...
}
Also keep in mind, that functions like getline(myFile, line) or myfile >> row will not terminate your program if the file is completly read or something.
I'm trying to make a program that will open a txt file containing a list of names in this format (ignore the bullets):
3 Mark
4 Ralph
1 Ed
2 Kevin
and will create a file w/ organized names based on the number in front of them:
1 Ed
2 Kevin
3 Mark
4 Ralph
I think I'm experiencing trouble in line 40, where I try to compare the numbers stored in strings with a number stored in an int.
I can't think of any other way to tackle this, any advice would be wonderful!
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
using namespace std;
int main()
{
ifstream in;
ofstream out;
string line;
string collection[5];
vector <string> lines;
vector <string> newLines;
in.open("infile.txt");
if (in.fail())
{
cout << "Input file opening failed. \n";
exit(1);
}
out.open("outfile.txt");
if (out.fail())
{
cout << "Output file opening failed. \n";
exit(1);
}
while (!in.eof())
{
getline(in, line);
lines.push_back(line);
}
for (int i = 0; i < lines.size(); i++)
{
collection[i] = lines[i];
}
for (int j = 0; j < lines.size(); j++)
{
for (int x = 0; x < lines.size(); x--)
{
if (collection[x][0] == j)
newLines.push_back(collection[x]);
}
}
for (int k = 0; k < newLines.size(); k++)
{
out << newLines[k] << endl;
}
in.close( );
out.close( );
return 0;
}
Using a debugger would tell you where you went wrong, but let me highlight the mistake:
if (collection[x][0] == j)
You're expecting a string like 3 Mark. The first character of this string is '3', but that has the ASCII value of 51, and that is the numerical value you'll get when trying work with it is this way! This will never equal j, unless you've got a lot of lines in your file, and then your search system will not work at all like you wanted. YOu need to convert that character into an integer, and then do your comparison.
C++ offers many way to process data via streams, including parsing simple datafiles and converting text to numbers and vice versa. Here's a simple standalone function that will read a datafile like you have (only with arbitrary text including spaces after the number on each line).
#include <algorithm>
// snip
struct file_entry { int i; std::string text; };
std::vector<file_entry> parse_file(std::istream& in)
{
std::vector<file_entry> data;
while (!in.eof())
{
file_entry e;
in >> e.i; // read the first number on the line
e.ignore(); // skip the space between the number and the text
std::getline(in, e.text); // read the whole of the rest of the line
data.push_back(e);
}
return data;
}
Because the standard way that >> works involves reading until the next space (or end of line), if you want to read a chunk of text which contains whitespace, it will be much easier to use std::getline to just slurp up the whole of the rest of the current line.
Note: I've made no attempt to handle malformed lines in the textfile, or any number of other possible error conditions. Writing a proper file parser is outside of the scope of this question, but there are plenty of tutorials out there on using C++'s stream functionality appropriately.
Now you have the file in a convenient structure, you can use other standard c++ features to sort it, rather than reinventing the wheel and trying to do it yourself:
int sort_file_entry(file_entry a, file_entry b)
{
return a.i < b.i;
}
int main()
{
// set up all your streams, etc.
std::vector<file_entry> lines = parse_file(in);
std::sort(lines.begin(), lines.end(), sort_file_entry);
// now you can write the sorted vector back out to disk.
}
Again, a full introduction to how iterators and containers work is well outside the scope of this answer, but the internet has no shortage of introductory C++ guides out there. Good luck!
I'm new to c++ coding. I'm trying to write a function that opens specified ".txt" files(I fed up with coping/pasting multiple times).What I need to realize:
Specify filename;
read data and save to double(type) array;
return array;
As far as I understood, c++ can't return array, but it can return pointer. The problem is: how to use it? Any help will be appreciated. :)
P.S My draft code (it's working):
double arr[10];
fstream file;
file.open("input.txt");
if(file.is_open()){
while(file.good()){
for(int i = 0 ; i < 10 ; i++){
file >> arr[i];
}
}
file.close();
}else{
cout<<"[ERROR]: File \"input.txt\" wasn't found!"<<endl;
cout<<"[INFO]: Terminating program...";
Sleep(1000);
exit(0);
}
I dunno how to write as a function. Moreover I dunno how to use it
To start, try this:
std::vector<double> theFunction(const std::string &filename)
{
std::vector<double> arr(10);
std::fstream file(filename);
if (file)
{
for (int i = 0 ; i < 10 && file.good(); i++)
file >> arr[i];
}
return arr;
}
std::vector<double> result = theFunction("input.txt");
if (result.empty())
// Can not read the file
When i read TestData.txt file it gives me wrong output. What am i doing wrong. I am using int array so i can do MergeSort after saving data into array.
TestData.txt
-------------------
31791 564974 477059 269094 972335
739154 206345 634644 227684 398536
910177 507975 589785 67117 395140
598829 372499 364165 450187 996527
700285 263407 918021 661467 457544
656297 846316 221731 240676 68287
913 141702 845802 477617 109824
{
int myArray[1000];
int i;
//reading givin data
const char* filename= "TestData.txt";
ifstream file(filename);
if(file.is_open())
{
for(i = 0; i <=999; ++i)
{
file >> myArray[i];//storing data to array
}
}
Need to check if you ifstream is end of file, in that case you get garbage value from out of the file bound.
With One modification, the code would be OK.
Change:
for(i = 0; i <=999; ++i)
to:
for(i = 0; i <=999 && !file.eof(); ++i)
You are reading 1000 enties from your file which contains clearly less than 1000 integers.
The first values of your array must be correct, but after you reach the end of your file the operator>> will not ready anything.
For example here is one way to write it:
const char* filename= "TestData.txt";
std::vector<int> myArray;
std::ifstream file(filename);
if(file.is_open())
{
int v;
while(file >> v) {
myArray.push_back(v);
}
}
int if I'm not wrong can keep data from -32768 to 32767.
So if u have bigger values than that (which you have, from your source file), you won't have the results you are expecting.
btw, it would be nice to know also what output you are getting.
I am writing a short program to sort an array of integers. I am having trouble opening my input file which is "prog1.d". The assignment has asked to create a symbolic link in the programs directory, and I after creating the object & executable, we invoke the program as follows...
prog1.exe < prog1.d &> prog1.out
I know my bubble sort works correctly & efficiently because I have used my own test 'txt' file.
The assignment says:
Your program gets the random integers from stdin and puts them in an array, sorts the integers in the array in ascending order, and then displays the contents of the array on stdout.
How do I read the file using 'cin' until EOF & add the integers to my array a[] ?
Here is my code so far:
int main( int argc, char * argv[] )
{
int a[SIZE];
for ( int i=1; i<argc; i++)
{
ifstream inFile; // declare stream
inFile.open( argv[i] ); // open file
// if file fails to open...
if( inFile.fail() )
{
cout << "The file has failed to open";
exit(-1);
}
// read int's & place into array a[]
for(int i=0; !inFile.eof(); i++)
{
inFile >> a[i];
}
inFile.close(); // close file
}
bubbleSort(a); // call sort routine
printArr(a); // call print routine
return 0;
}
I know that opening a stream is the wrong way to do this, I just was using it for a test 'txt' file I was using to make sure my sorting worked. The teacher said we should redirect the input to 'cin' like someone was entering integers on a keyboard.
Any help would be greatly appreciated.
When you're using redirection on the command line, argv does not contain the redirection. Instead, the specified file simply becomes your stdin/cin. So you don't need to (and shouldn't try to) open it explicitly -- just read from the standard input, as you would read from the terminal when input isn't redirected.
Since you are piping the file on the stdin, you don't have the file name on argv[1], just read the stdin as the user was typing at the console, for example using cin:
cin.getline (...);
The other answers are completely correct, but here's the rewritten code to claify:
int main( int argc, char * argv[] )
{
int a[SIZE];
int count = 0;
// read int's & place into array a[]
//ALWAYS check the boundries of arrays
for(int i=0; i<SIZE; i++)
{
std::cin >> a[i];
if (std::cin)
count = count + 1;
else
break;
}
bubbleSort(a, count); // call sort routine
printArr(a, count); // call print routine
return 0;
}
As everyone has stated, use std::cin directly -- you don't need to open the input file, your shell has already done that for you.
But, please, please, please, don't use cin.eof() to test to see if you have reached the end of your input. If your input is flawed, your program will hang. Even if your input isn't flawed, your program may (but won't necessarily) run the loop one extra time.
Try this loop instead:
int a[SIZE];
int i = 0;
while( std::cin >> a[i]) {
++i;
}
Or, add robustness by using std::vector which will automatically grow:
std::vector<int> a;
int i;
while(std::cin >> i) {
a.push_back(i);
}
Or, use generic algorithms:
#include <iterator>
#include <algorithm>
...
std::vector<int> a;
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(a));