I have this problem where I must read data from n books: title, author, price( the pret variable), the number of copies (the nr variable). The variable val represents the "value" of the book, which is price* number of copies.
We only use arrays in school, not vectors of strings therefore all of our problems have fixed-sized strings. Example of the file we are reading from:
3
Ion
Liviu Rebreanu
100
10
Mara
Ioan Slavici
50
3
Poezii
Mihai Eminescu
60
20
I need to print out the data read for every book and also the "value" of it. And I also need to print the data of the book with the highest value afterwards. I'm working in Code::Blocks 13.12 because it'a school assignment. I have no idea why, but it reads only the data for my first book. So therefore it prints a lot of nonsense after that reading. What's wrong with it?
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;
struct carte
{
char t[50], a[50];
int pret, nr, val;
} v[100];
int main()
{
int n, i, maxx=0, x, j;
ifstream fin ("carte.txt");
fin>>n;
fin.get();
for (i=1; i<=n; i++)
{
fin.get(v[i].t, 50); cout<<v[i].t<<" ";
fin.get();
fin.get(v[i].a, 50);
fin.get(); cout<<v[i].a<<" ";
fin>>v[i].pret>>v[i].nr; cout<<v[i].pret<<" "<<v[i].nr<<endl;
v[i].val=v[i].pret*v[i].nr;
if(v[i].val>maxx)
{
maxx=v[i].val;
x=i;
}
}
for(i=1; i<=n; i++)
{
cout<<v[i].t<<" "<<v[i].a<<" "<<v[i].pret;
cout<<" "<<v[i].nr<<" "<<v[i].val<<endl;
}
cout<<v[x].t<<endl;
return 0;
}
Before you compute the total number of copies (pret * nr) you should make an extra call to fin.get() to deal with what I think is a carriage return. I noticed this after reformatting the code a bit to show the output in terms of a line of comma separated values, or csv.
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;
struct carte
{
char t[50], a[50];
int pret, nr, val;
} v[100];
int main()
{
int n, i, maxx=0, x, j;
ifstream fin ("carte.txt");
fin>>n;
fin.get();
cout << "Read: " << n << endl;
cout << "Title, Author, Price, Copies" << endl;
for (i=1; i<=n; i++) {
fin.get(v[i].t, 50); cout<<v[i].t<<",";
fin.get();
fin.get(v[i].a, 50);
fin.get(); cout<<v[i].a<<",";
fin>>v[i].pret>>v[i].nr; cout<<v[i].pret<<","<<v[i].nr<<endl;
fin.get();
v[i].val=v[i].pret*v[i].nr;
if(v[i].val>maxx) {
maxx=v[i].val;
x=i;
}
}
cout << "Output: " << endl;
for(i=1; i<=n; i++) {
cout<<v[i].t<<" "<<v[i].a<<" "<<v[i].pret;
cout<<" "<<v[i].nr<<" "<<v[i].val<<endl;
}
cout<<v[x].t<<endl;
return 0;
}
Read: 3
Title, Author, Price, Copies
Ion,Liviu Rebreanu,100,10
Mara,Ioan Slavici,50,3
Poezii,Mihai Eminescu,60,20
Output:
Ion Liviu Rebreanu 100 10 1000
Mara Ioan Slavici 50 3 150
Poezii Mihai Eminescu 60 20 1200
Poezii
Related
I want a right aligned number pattern using setw for giving spaces
either the spaces disappear when setw is less than no. of printed numbers or it makes any random pattern.
My Code is below:
#include <iostream>
#include<iomanip>
using namespace std;
int main()
{
int space, n,i,j,k,l,m;
cin>>n;
for (k = n; k <=2*n-1; k++)
{
cout<<setw(k);
}
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
cout<<j;
}
cout<<endl;
}
return 0;
}
The output I am getting is (n=5):
1
12
123
1234
12345
The output I want is (n=5):
1
12
123
1234
12345
The first for loop is not necessary.
setw sets the field length for the next field (the field following setw). So if the next field is an empty string, setw(x) will just reserve x characters space. Also, the value x should be equal to n - i (if no. of characters to be printed is 1, you need (5 - 1) i. e. 4 spaces)
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n, i, j;
cin >> n;
for (i = 1; i <= n; i++) {
cout << setw(n - i) << "";
for (j = 1; j <= i; j++) {
cout << j;
}
cout << endl;
}
return 0;
}
Before I ask anything, I should mention that I have a shaky foundation in C++. Let me know if I'm not being clear on anything and I will do my best to clarify.
My coding problem here is reading a series of 24-hour time values, with no seconds included, and storing them into an array of a structure. Reading the hours and minutes in integer format, and storing it into an array of structures is what I'm not understanding with this. In the text file, the first number in each row is the 24-hour time, and the second number is the amount of minutes that I need to modify the time with. I'm stuck frozen at just reading the times in to begin with.
This is the code I have so far.This is the result of the code.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int size = 7;
int i;
struct Times {
int T;
int M;
};
Times clock[7];
ifstream infile;
infile.open("times.txt");
for (i=0; i<size; i++){
infile>>clock[i].T>>clock[i].M;
}
for (i=0; i<size; i++){
cout<<clock[i].T << " "
<<clock[i].M <<endl;
}
}
Here is the contents of the text file:
6:45 39
12:00 73
0:00 4
23:59 1
22:45 70
11:59 1
14:15 95
Here is the updated code which seems to work:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int size = 7;
int i;
char colon;
struct Times {
int hour;
int minute;
int M;
};
Times clock[7];
ifstream infile;
infile.open("times.txt");
for (i=0; i<size; i++){
infile>>clock[i].hour>>colon>>clock[i].minute>>clock[i].M;
}
for (i=0; i<size; i++){
cout<<clock[i].hour << " "
<<colon << " "
<<clock[i].minute << " "
<<clock[i].M
<<endl;
}
}
Note that each line of your file contains three integral values, not two, and that a colon will stop reading in an integral value (formatted input for integrals will skip leading white spaces and even new line characters, but not "leading" colons). If you want to read an integral value that follows a colon, you'll need to skip the colon.
You could do this by reading in the colon into a variable of type char (and ignoring it afterwards). The code could look as follows:
int main()
{
int hour,minute,x;
char colon;
stringstream s { "15:43 10\n16:48 20\n" };
while (s >> hour >> colon >> minute >> x) {
cout << "H:M=" << hour << ":" << minute << "; times=" << x << std::endl;
}
}
Output:
H:M=15:43; times=10
H:M=16:48; times=20
Update 1: I need help with this the second part of this. I am asking the user to input numbers and to stop by using a zero. But then I want to display that code back. This is how far I got because when I want to display it it gives me different numbers. I'm ignoring user errors assuming when they input the first time it will be correct. But I do want them to input negative numbers.
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
float data;
int count=0;
int*arr=new int[count];
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
cin>>data;
for (; data != 0 ; ++count)
{
cin>>data;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
system ("pause");
return 0;
}
**Update 2:**This code is part of a bigger project I'm working on. My professor is never going to see the code he just cares that it is working. The design of my code is not a priority in this case. Also I have never used std::vector before so I needed another way to do it. But this is what I did and it worked fine. I also commented off delete []arr because my code wouldn't run properly if I didn't do that.
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
double data;
int count=0;
double *arr =new double[count];
//get data
cout<<"Please enter floating point data."<<endl;
cout<<"After the last number has been entered press 0 (zero)"<<endl;
do
{
cin>>arr[count];
data = arr[count];
count++;
}while(data != 0);
//display back data
cout<<"The numbers entered are: "<<endl;
for(int i=0; i<(count-1); i++)
{
cout<<arr[i]<<endl;
}
//delete []arr;
system ("pause");
return 0;
}
The given example code,
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
float data;
int count=0;
int*arr=new int[count];
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
cin>>data;
for (; data != 0 ; ++count)
{
cin>>data;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
system ("pause");
return 0;
}
… has many issues:
Coding: using float for no reason.
The default floating point type in C and C++ is double. E.g. the literal 3.14 is of type double, and any float value is promoted to double when passed to variadic C function. Only use float where a requirement is imposed by the context, e.g. a C API, or storing a zillion values in limited memory.
Coding: using a raw array and a new-expression.
The task is trivial when using std::vector. It's not a good idea to reinvent the wheel again and again. An exercise that requires you to reinvent std::vector or its most basic features should be very clear about that aspect: this isn't, so presumably reinvention is not required or what it's about.
Design: signalling end-of-input via special value.
That value can't be inputted.
Coding: an input loop that doesn't store the numbers.
Each number is stored in the same variable as the previous number, erasing the previous number. Store the numbers in a std::vector. E.g. you can use the push_back method.
Coding: inconsistent convention for newline on output.
Either use endl, or "\n", as default. Don't mix them randomly. Consistency is very important because someone reading the code, who assumes a competent programmer, must treat every departure from the established defaults as being due to some reason. When there is no reason this wastes time and effort.
Tool usage: the system( "pause" ) is silly, counter-productive & non-portable.
In Visual Studio, which it appears you're using, just run the program via Ctrl+F5. Or place a breakpoint on the last right brace of main, and run the program in the debugger via F5.
Coding: the return 0; is superfluous.
main is the only function that has a default return value. It has that in both C and C++. The default, 0 for success, is there to be used.
Example code with the above points, plus some, fixed.
This code is for C++11 or later so it won't compile directly with Visual C++ 2010.
I leave it as an exercise for you to translate it to C++03, which is what your current compiler can handle. Do consider upgrading. It's a free tool.
#include <iostream>
#include <iomanip> // std::setw
#include <string> // std::(string, stod)
#include <vector> // std::vector
using namespace std;
using Half_float = float; // Most often a silly choice.
using Float = double; // Default in C++.
using Extended_float = long double; // Same as double in Visual C++.
auto read_line()
-> string
{ string line; getline( cin, line ); return line; }
auto main() -> int
{
cout << "Please enter floating point numbers like " << 3.15 << ", one per line.\n";
cout << "After the last number just press return again (i.e. a blank line).\n";
vector<Float> numbers;
for( ;; )
{
cout << "#" << numbers.size() + 1 << "? ";
string const line = read_line();
if( line.empty() )
{
break;
}
numbers.push_back( stod( line ) ); // Here you CAN do input validation.
}
cout << numbers.size() << " numbers entered.\n";
cout << "\n";
cout << "The numbers entered were: \n";
for( int i = 0; i < int( numbers.size() ); ++i )
{
cout << setw( 3 ) << i << ": " << numbers[i] << "\n";
}
}
If you have C++ 11 or above, use auto
replace
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
with
for(auto v: arr){
cout << v << endl;
}
Please remember, you'll need compiler supporting C++11 to use auto.
If C++ < 11, Use std::for_each
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
void print(float v){
cout << v << endl;
}
int main ()
{
float data;
int count=0;
std::vector<float> arr;
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
while(cin>> data && data != 0)
{
arr.push_back(data);
++count;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
std:for_each(arr.begin(), arr.end(), print);
cout<<endl;
system ("pause");
return 0;
}
The code will access out-of-bounds of arr, which has zero elements, unless you enter 0 for the first prompt.
You didn't assign what you read to "elements or arr" (actually there will be no elements in arr) at all.
There will be no reason why you should use array of int to store float data.
You should use std::vector, which works as variable-size array.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main ()
{
float data;
int count=0;
vector<float> arr;
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
while(cin >> data && data != 0)
{
arr.push_back(data);
}
count = arr.size();
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
return 0;
}
Hey guys I am new to reading txt files to arrays, so I need to read this txt file temperature.txt to a two dimensional array. Here is the file I need to read, and the code I tried writing up it complies but Im not sure if it is reading it correctly
T(F) R1 R2 R3 R4
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
UPDATE I re did this again without looking at your answers but will this work ?
using namespace std;
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
int main ()
{
char temp[11] [5];
ifstream tempin ("c:\\mydoc2\\temperaturedata.txt");
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]>>temp[8]
>>temp[9]>>temp[10];
while(!tempin.fail())
{
cout<< temp[0] << " " << temp[1] << " " << temp[2] << " " << temp[3]<< " " << temp[4]<< " " << temp[5] << " " << temp [6] <<
" " << temp [7] << " " << temp[8] << " " << temp[9] << " " << temp[10];
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]
>>temp[8]>>temp[9]>>temp[10];
}
cout << endl << endl;
system("pause");
return 0;
}
You have a string myArray[5]; but you're reading 55 elements - that should not work!
There are lots of errors in your code.
1) You have written a read function but you never call it, so it never executes.
2) There is no 2D array in your code. 2D arrays look like this double myArray[10][10];. (that's a 10 by 10 2D array of doubles).
3) You're trying to read floating point numbers, but your array is an array of strings.
4) Your array is size 5 but you try and read 55 items into it.
5) After you open the file you have an infinite loop which just prints out "No file\n". Not sure why you want to print out error messages in a loop. Normally you just print an error message once.
I could go on, but I think the main point is that you're a beginner, and you currently aren't able to write three lines of code without introducing an error (sorry to be harsh but based on the above that is true). So the important lesson is that you should not try to write more than three lines of code at once.
Try something like this
a) Write some code which opens a file, test it and check that it does open the file
b) Add some code to a) to read one number, test it and check that it does read one number.
c) Replace the read one number code with code that reads a 1D array of numbers. Test it and check that it works.
etc. etc.
The point is to build up gradually to the program you want, and test each stage as you go. I can't emphasise how important that is. Every professional programmer works like this, but because you're a beginner the steps you have to take are much smaller than an experienced programmer.
Try something like this:
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
ifstream myfile ("C:/temps.txt");
int dim_x = 12;
int dim_y = 5;
double temps[dim_x][dim_y] ;
//init the array if neccesary
for(int x = 0;x<dim_x;x++)
for(int y = 0; y<dim_y;y++)
temps[x][y]=0;
if (myfile.is_open()){
for ( int x=0; getline (myfile,line); x++ ){
int y=0;
istringstream iss(line);
while(iss){
string sub;
iss >> sub;
temps[x][y] = ::atof(sub.c_str());
y++;
}
}
myfile.close();
}
cout << "TEMPS:" << endl;
for(int x = 0;x<dim_x;x++){
for(int y = 0; y<dim_y;y++)
cout<<temps[x][y]<<" ";
cout<<endl;
}
return 0;
}
I made some improvements
#include <fstream>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
void read ();
int main ()
{
read();
return 0;
}
void read()
{
ifstream indata(".\\temperaturedata.txt");
if(indata == NULL)
{
cout<< "Opening file failed."<< endl;
return;
}
const int columns = 5;
const int rows = 11;
double myArray[rows][columns];
string tmp;
getline(indata, tmp);
for(int i = 0; i < rows; ++i)
{
for (int j = 0; j < columns; ++j)
{
cout << "\t" << flush;
indata >> myArray[i][j];
cout.setf(ios::fixed);
cout << setprecision(2) << myArray[i][j] <<flush;
}
cout << endl;
}
indata.close();
}
If the content of your file is like this:
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
then, it's quite easy for you to get these values. But there are some errors in your code:
while(!indata.fail()) : This line will cause a dead loop. Use if(!indata) instead.
You will need a 2-dimension array of type double instead of string
Here is what could work:
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
using namespace std;
void read ();
int main ()
{
read();
system("PAUSE");
return 0;
}
void read()
{
ifstream indata("E:\\temperature.txt"); //that's my path,you should use yours.
if(!indata)
{
cout<<"No file."<< endl;
}
if(indata.is_open())
{
double myArray[11][5];
for(int i = 0; i < 11; ++i)
{
for(int j = 0; j < 5; ++j)
{
indata >> myArray[i][j];
//cout<<myArray[i][j]<<"\t";
}
//cout<<endl;
}
}
}
This could work when your txt file doesn't include the first line:T(F) R1 R2 R3 R4, if this line did exit,you should use getline() to move your file pointer to the second line, where you could read the data.
Below is the program I wrote to find sum of a subarray from given array, however somehow I am not getting how can I get rid of the sentinel value (-32767 in this case)? and how can I optimise it?
and how can I keep track of range of max subarray?
#define EVALUE -32767
using namespace std;
int findMaxSubArray(vector<int>,int low,int high);
int findMaxSubArray_Mid(vector<int>,int low,int high);
int main()
{
vector<int> v;
int j=0;
cout << "Enter array values(-32767 to end): ";
while(1)
{
cin >> j;
if (EVALUE==j)
break;
v.push_back(j);
}
if(v.size()!=0)
cout << "Max sum is: " << findMaxSubArray(v,0,v.size()-1) << "\n";
else
cout << "No array elements entered, exiting...\n";
system("pause");
return 0;
}
int findMaxSubArray(vector<int> v, int low, int high)
{
if(low==high) return v[low];
int max_mid_sum=findMaxSubArray_Mid(v,low,high);
int max_left_sum=findMaxSubArray(v,low,(low+high)/2);
int max_right_sum=findMaxSubArray(v,(low+high)/2+1,high);
if (max_mid_sum>max_left_sum) return (max_mid_sum>max_right_sum?max_mid_sum:max_right_sum);
else return(max_left_sum>max_right_sum?max_left_sum:max_right_sum);
}
int findMaxSubArray_Mid(vector<int> v,int low,int high)
{
int mid=high/2;
int max_left_sum=0;
int max_right_sum=0;
int sum=0;
for(int i=mid;i>=low;--i)
{
sum+=v[i];
if(sum>max_left_sum)
{
max_left_sum=sum;
}
}
sum=0;
for(int i=mid+1;i<=high;++i)
{
sum+=v[i];
if(sum>max_right_sum)
{
max_right_sum=sum;
}
}
return (max_right_sum+max_left_sum);
}
When reading from a textfile, the last character that cin will get is the "EOF" character, or end of file character. You can send this character to your program in the command line with control+d. You're going to want to check for this rather than -32767.
This is a basic program that should identify a simple fix for your problem:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v;
int j;
cout << "Enter array values (Control+D (EOF) to end): ";
cin >> j;
while(cin.good())
{
v.push_back(j);
cin >> j;
}
return 0;
}
If you want to get really smart you can use the below and it will directly insert the contents of the memory at cin (from the beginning until EOF) into your vector. As far as running time goes, this will probably be faster than your solution and the above solution.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
vector<int> v;
cout << "Enter array values (Control+D (EOF) to end): ";
istream_iterator<int> in(cin);
istream_iterator<int> eof;
copy(in, eof, back_inserter(v));
ostream_iterator<int> out(cout, "\n");
copy(v.begin(), v.end(), out);
return 0;
}
About the sentinel, IIRC with Control+D you close standard input(may depend of OS). That will cause the << to fail (I am not sure how, probably you'll have to catch an exception).
Anyway, the rest of the code is just a recursive (binomial) adding of the vector. You can sustitute all of it with a simple for
for(int i = 0; i < v.size(); i++) {
total += v[i]
}
The question about range of max subarray is already managed by the class Vector