Retrieve the first value from a map - c++

I want to retrieve the first value of speed in from the typedef struct variable which I have added into the map. Right now my code is returning all the values from the CSV file which I have read. How do I get it to return only the first value to do a comparison to get the max value from the entire column?
I have tried using map.begin()->((*it).second).speed) but it does not work.
#include <iostream>
#include <fstream>
#include <string>
#include "Date.h"
#include "Time.h"
#include <stdlib.h>
#include <map>
using namespace std;
typedef struct
{
Time t;
float speed;
int solar;
}
WindLogType;
date d;
multimap<date, WindLogType> windlog;
ifstream input , csv;
ofstream output;
string filename;
int number,choice;
string *filelist = NULL;
WindLogType T1;
int main()
{
output.open("data/met_index.txt");
cout << "Enter number of file to read : " << endl;
cin >> number ;
for(int i =0; i< number ; i++)
{
cout << "Enter File name : " << endl;
cin >> filename;
output << filename << endl;
}
filelist = new string[number];
output.close();
input.open("data/met_index.txt", ios::in);
if(!input.is_open())
{
cout<< "File not found."<<endl;
return 0;
}
else
{
string line, line2;
while(getline(input, line, '\n'))
{
//cout << line << endl;
line = "data/" + line;
for(int i =0; i<number; i++)
{
filelist[i] = line;
cout << filelist[i];
csv.open(filelist[i].c_str());
string line,sDay, sMonth, sYear, sHH, sMM;
while(getline(csv,line2, '\n' ))
{
//cout << line2 << endl;
getline(csv, sDay,'/');
getline(csv, sMonth,'/');
getline(csv, sYear,' ');
getline(csv, sHH,':');
getline(csv, sMM,',');
int day1 = atoi(sDay.c_str());
int month1 = atoi(sMonth.c_str());
int year1 = atoi(sYear.c_str());
int hour1 = atoi(sHH.c_str());
int min1 = atoi(sMM.c_str());
float s1 = 0.0;
int sr = 0;
for (int i=0; i<10; i++)
{
csv >> s1;
csv.ignore(100, ',');
}
for(int j =0; j<18; j++)
{
csv >> sr;
csv.ignore(50,',');
}
T1.t.setTime(hour1, min1);
T1.speed = s1;
T1.solar = sr;
d.setDate(day1, month1, year1);
windlog.insert(pair<date, WindLogType>(d, T1));
multimap<date, WindLogType> :: iterator it;
for(it =windlog.begin(); it!= windlog.end(); ++it)
{
int max_value = ((*it).second).speed;
if((*it).second.speed > max_value){
max_value = ((*it).second).speed;
}
cout << max_value<<endl;
}
}
csv.close();
}
/**/
}
input.close();
input.clear();
//input.open(filelist[0].c_str(), ios::in);
}
return 0;
}

Your are printing max_value everytime.
Move the lines that find the maximum value after you've inserted everything, i.e., after the csv.close() for example. Also, do not print the maximum while searching for it but after you've iterated over all the elements.
multimap<date, WindLogType> :: iterator it =windlog.begin();
int max_value = ((*it).second).speed;
for(++it ; it!= windlog.end(); ++it)
{
if((*it).second.speed > max_value){
max_value = ((*it).second).speed;
}
}
cout << max_value<<endl;
Of course, be sure the map is not empty.
EDIT
WindLogType.speed is a float and you're using an integer when finding the maximum, it should be float too. Probably you already know it, but since C++11 you can use the auto specifier to let the compiler deduce automatically the correct type based on the assignment expression. It is available since Visual Studio 2010 and gcc 4.4 (for gcc you have to include the --std=c++11 option).
if (!windlog.empty()) {
auto it = windlog.begin(); // 'it' is an iterator
auto max_value = it->second.speed; // you're now sure it uses the same type
for(++it; it!= windlog.end(); ++it) {
max_value = std::max(it->second.speed, max_value);
}
std::cout << max_value << std::endl;
} else {
std::cout << "Empty map" << std::endl;
}

Related

C++ Read from input file into struct array

I am learning C++, and one of my lessons is having me read from a file into an an array of structs(is that how I refer to this?). I am having issues where my code compiles fine, but sits and spins on a blank screen. I am fairly sure that the issue lies with how I read the file in.
#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
ifstream inputFile;
const int SIZE = 150;
int count = 0;
int index[150] = {};
inputFile.open("lab9input.dat");
struct Student {
string name;
int studentID;
int credits;
int gpa;
} students[SIZE];
while (count < SIZE && inputFile >> students[count].name >>
students[count].studentID >>
students[count].credits >> students[count].gpa) {
count++;
}
cout << endl << "The highest GPA student(s) is: " << endl;
for (int i = 0; i < count; i++) {
int high = 0, j = 0;
if (students[i].gpa > high) {
high = students[i].gpa;
for (int k = 0; k < 150; k++) {
index[k] = 0;
}
index[j] = i;
}
if (students[i].gpa == high) {
j++;
index[j] = i;
}
}
for (int i = 0; i < 150; i++) {
if (index[i] != 0) {
cout << students[index[i]].name << " "
<< students[index[i]].studentID << " "
<< students[index[i]].credits << " " << setprecision(2)
<< students[index[i]].gpa;
}
}
}
For reference, my text file looks like this:
Wesley s012980520 30 3.5
Allen s094589012 120 3.29
Jim s980469026 145 3.85
Luke s098419346 180 3.6
Helen s124598670 60 3.85
Chole s123309870 60 3.0
Am I missing something glaringly obvious? Thank you for the help!
Here are some of the problems in your code:
Data type of different variables: Your data (say Wesley s012980520 30 3.5) is of the format string string int float, which clearly does not match with the types in your struct Students.
To fix this, simply change your struct to:
struct Student {
string name;
string studentID;
int credits;
float gpa;
} students[SIZE];
Also, high should be float (as it stores gpa).
high and j become 0 on each iteration. Move high above the loop and j to init-list of the loop, like this:
float high = 0;
for (int i = 0, j = 0; i < count; i++)
index[j] = i; (first-occurrence) assigns index of student with highest gpa to index[j] but prior to this, j = 0 (although the index array is reset).
The second if condition (if (students[i].gpa == high)) inside the loop assigns the index of student with highest gpa to index[1], if the conditional block above it has executed. Make it else if to prevent redundancy.
Suggestions:
There is a setprecision(2), if you have put it display 3.6 as 3.60 then you need to add fixed before that.
There is no need to traverse whole index array, you simply need to do that from 0 to count.
Remove magic number 150 from your code, use the constant you have declared instead.
Put an endline ('\n') after printing each Student object.
Don't use std::endl to put simple newline characters. Use it only if you also need to flush the stream.
Avoid putting using namespace std; at top of your code.
Why put " when ' can do the job ;).
ifstream inputFile and inputFile.open can be written in a single line like : ifstream inputFile("...").
Corrected Code (doesn't work if name has spaces in it):
#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std; // <-- (10), remove this yourself
int main() {
ifstream inputFile("lab9input.dat"); // <-- (12)
const int SIZE = 150;
int count = 0;
int index[SIZE] = {}; // <-- (7)
struct Student {
string name;
string studentID; // <-- (1)
int credits;
float gpa; // <-- (1)
} students[SIZE];
while (count < SIZE && inputFile >> students[count].name >>
students[count].studentID >>
students[count].credits >> students[count].gpa)
count++;
cout << "The highest GPA student(s) is(are): \n"; // <-- (9)
float high; // <-- (1), (2)
for (int i = 0, j = 0; i < count; i++) { //<-- (2)
if (students[i].gpa > high) {
high = students[i].gpa;
for (int k = 0; k < 150; k++) index[k] = 0;
j = 0; // <-- (3)
index[j] = i;
} else if (students[i].gpa == high) // <-- (4)
index[++j] = i;
}
for (int i = 0; i < count; i++) // <--(6)
if (index[i] != 0)
cout << students[index[i]].name << ' ' << students[index[i]].studentID
<< ' ' << students[index[i]].credits << ' ' << fixed // <-- (5)
<< setprecision(2) << students[index[i]].gpa << '\n'; // <--(8)
}
Better code to do the same thing:
#include <algorithm>
#include <cctype>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
struct Student {
std::string name, studentID;
int credits;
float gpa;
friend std::ostream &operator<<(std::ostream &, const Student &);
friend std::istream &operator>>(std::istream &, Student &);
};
std::ostream &operator<<(std::ostream &out, const Student &s) {
out << s.name << ' ' << s.studentID << ' ' << s.credits << ' ' << s.gpa
<< '\n';
return out;
}
std::istream &operator>>(std::istream &in, Student &s) {
s.name.clear();
std::string str;
while (in >> str && std::none_of(str.begin(), str.end(), ::isdigit))
s.name += str + ' ';
s.name.pop_back();
s.studentID = str;
in >> s.credits >> s.gpa;
return in;
}
int main() {
std::ifstream is("lab9input.dat");
std::vector<Student> v(std::istream_iterator<Student>(is), {});
auto max_gpa = std::max_element(v.begin(), v.end(), [](auto &a, auto &b) {
return b.gpa > a.gpa;
})->gpa;
std::cout << "The highest GPA student(s) is(are): \n";
for (auto &i : v) if (i.gpa == max_gpa) std::cout << i;
}

How to fix vector not printing values from file

I am trying to get some values line by line from a text file:
17.09 284.60 486.01 34.12 12.04 1.20 2.33 36.85 73.44
31.25 196.09 323.26 69.76 47.33 79.82 11.42 27.97 66.61
28.76 41.45 992.29 1.29 42.33 10.83 19.16 5.86 1.88
Taking these values and putting it into a vector. Each row has values to be used in a calculation.
My code:
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <vector>
using namespace std;
int main() {
ifstream xfile;
string input;
double num=0;
int count = 0;
vector <double> myvector;
cout << "Input the file: ";
cin >> input;
xfile.open(input);
if (xfile.is_open()) {
cout << "File accessed!" << endl;
while (getline(xfile, input)) {
count++;
myvector.push_back(num);
}
}
else {
cout << "File opening failed!"<<endl;
}
cout << "Numbers of lines in the file : " << count << endl;
for (int i = 0; i < myvector.size(); i++) {
cout << myvector[i] << "\t";
}
cin.fail();
return 0;
}
My output is somewhat correct, only that it is printing out just zeroes:
https://ibb.co/xqwT1hR
EDIT: the input is for the name of file. "ahu_long.txt"
You never used your num variable.
double num=0;
....
....
size_t pos = 0;
std::string token;
while (getline(xfile, input)) {
count++;
// you need convert your "input" to a double and save it to "num"
while ((pos = input.find(" ")) != std::string::npos) {
token = input.substr(0, pos);
// std::cout << token << std::endl;
num = atof(token.c_str());
myvector.push_back(num);
input.erase(0, pos + delimiter.length());
}
}
Change your variable with what you read from the file.

read int per line c++ error needs solution

hey guys I need help for my read code seems not working properly here's the code. The problem is as shown in the picture, the compiler are supposed to display all 1 million int value but it seems that my write or the display code was wrong. It shows nothing like it's not even reading.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <omp.h>
#include <ctime>
#include <cstdlib>
using namespace std;
int* CreateArray( int*);
void shellSortParallel( int*, int);
void shellSortSequential(int*, int);
void InsertSort( int*, int, int, int);
int main()
{
int array_size = 1000000;
int n=0;
int* arr=new int[array_size];
ifstream fin("OUTPUT1.txt");
if(! fin)
{
cout << "File could not be opened." << endl;
}
else
{
cout << "File Opened successfully!!!. Reading data from file into array" << endl;
int data;
while(fin>>data)
{
arr[n] = data;
n++;
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < array_size; i++)
{
cout << arr[i];
}
}
fin.close();
int length = 1000000;
double endTime = 0, startTime = 0, totalTime = 0;
double start, end;
cout << "Program is now sorting using shell sort" <<endl;
startTime = time(NULL);
start = omp_get_wtime();// Start performance timer 1 run
shellSortParallel(arr, length);//Run the algorithm
end = omp_get_wtime();// End performance timer 1 run
endTime = time(NULL);
totalTime = endTime - startTime;
cout << "This is the time it took to run. " << totalTime << endl;// time in seconds
int stupid = 0;
cin >> stupid;
cout << "Program has completed all tasks!!" << endl;
return 0;
}
void shellSortParallel(int array[], int length)
{
int h;
int j = 0;
int temp = 0;
int i = 0;
for(h =length/2; h > 0; h = h/2)
{
#pragma omp parallel for shared( array, length, h, i) default(none)
for( i = 0; i < h; i++)
{
//int ID = omp_get_thread_num();
InsertSort(array, i, length, h);
}
}
}
void InsertSort(int arr[], int i, int length, int half)
{
//cout << ID << " ";
int temp = 0;
int j = 0;
for (int f = half + i; f < length; f = f + half)
{
j = f;
while(j > i && arr[j-half] > arr[j])
{
temp = arr[j];
arr[j] = arr[j-half];
arr[j-half] = temp;
j = j -half;
}
}
}
and here is the short version of the file that I'm going to read. Its a random number between 1 to 1million per line
2377763
88764877846
281327
60
625
86
646127818
14551
2177645
32033
1826761
555173
3415445377
32430
1101
any help would be much appreciate, thank you before
By if(fin>>data) you are not just testing, but retrieving data from stream. I suggest use ifs.good() for testing. Overall, you can write such a code instead
std::ifstream fin ("OUTPUT1.txt", std::ifstream::in);
char c = fin.get();
while (fin.good())
{
std::cout << c;
c = fin.get();
}
arr[n-1] = '\0'; is not correct because it's not an array of character so don't mind.
to correct it:
int data;
while(fin>>data)
{
arr[n] = data;
n++;
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < array_size; i++)
{
cout << arr[i];
}
why allocating such huge array of integers? use vector is a good thing:
vector<int> vec;
ifstream fin("OUTPUT1.txt");
int data;
while(fin >> data)
{
vec.push_back(data);
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << endl;
fin.close();
88764877846 out band of an integer which causes the loop stop reading so you have to either get values as strings then convert into __int64 or __int128
to read values as strings:
string sLine;
int nLines = 0;
ifstream fin("OUTPUT1.txt");
// first read to get number of lines
while(getline(fin, sLine))
nLines++;
//create an array of strings
string* pstrValues = new string[nLines];
// set the get pointer to the beginning of file because the previous read moved it
fin.clear();
fin.seekg(0, ios::beg);
int i = 0;
while(getline(fin, sLine))
{
pstrValues[i] = sLine;
i++;
}
cout << "Displaying Array..." << endl << endl;
for( i = 0; i < nLines; i++)
cout << pstrValues[i] << endl;
fin.close();
now you have an array of strings convert it to int values but you must convert to __int64 because as I said there are values bigger than size of int (4bytes)

how to save the sorted arrays in textfile?

I have a program that sorted arrays how can i save in text file?
for example: the sorted arrays is: 1, 2, 3, 4, 5.
how can i save in text file named. Sorted elements".
I've tried many ways but the sorted array wouldn't save in text file.
I am a newbie so I find it difficult.
here is my code.
#include <iostream>
using namespace std;
int main() {
cout << "Enter number of element:";
int n; cin >> n;
int a[n];
for(int i=0;i<n;i++)
{
cout << "element number " << (i+1) << " : ";
cin >> a[i];
}
int e=1, d=3;
int i, j, k, m, digit, row, col;
int length = sizeof(a)/sizeof(int);
int bmat[length][10];
int c[10];
for(m=1;m<=d;m++)
{
for(i=0;i<10;i++)
{
c[i]=-1;
}
for(i=0;i<length;i++)
{
digit=(a[i]/e)%10;
c[digit]++;
row=c[digit];
col=digit;
bmat[row][col]=a[i];
}
k=-1;
for(i=0;i<10;i++)
{
if(c[i]!=-1)
{
for(j=0;j<=c[i];j++)
{
k++;
a[k]=bmat[j][i];
}
}
}
e=e*10;
}
cout << endl;
cout << "Sorted array:" << endl;
for(int i=0;i<n;i++)
{
cout << a[i] << " , ";
}
cout << endl;
system("pause");
return 0;
}
//Use this code
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
int main()
{
int n = 0;
cout << "Enter number of element:";
cin >> n;
//Data Structure
std::vector<int> list;
//push back element in vector
for(register int i=0;i<n;++i)
list.push_back(rand()%10 + 1);
//do shuffling before sorting because rand() generates increasing order number
std::random_shuffle(list.begin(),list.end());
std::sort(list.begin(),list.end());
ofstream textfile;
textfile.open ("E:\\example.txt");
for(size_t i= 0;i<list.size();++i)
textfile << list[i] <<" ";
textfile.close();
}
If you can write the sorted array to std::cout, then you can write it to a file. In C++, the console is the same as a file.
Put this at the end of main:
cout << "Sorted array:" << endl;
print_array( std::cout, a, n ); // Show the results to the user.
std::ofstream save( "array.txt" ); // Open a new file (or overwrite).
print_array( save, a, n ); // Save the results for later.
system("pause");
return 0;
}
and put the printing code in a new function, which may be defined before main:
void print_array( std::ostream & s, int * a, int n ) {
for(int i=0;i<n;i++)
{
s << a[i] << " , ";
}
s << endl;
}
#include<iostream>
#include<fstream>
using namespace std;
int compare(int, int);
void sort(int[], const int);
int compare(int x, int y){
return(x > y);
}
void swap(int *x, int *y){
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void display(int array[], int n){
for (int i = 0; i<n; i++) {
cout << array[i] << " ";
}
cout << endl;
}
void writeToFile(int array[], int n){
ofstream myfile;
myfile.open("example.txt");
for (int i = 0; i<n; i++) {
myfile << array[i];
if (i != n - 1){
myfile << ", ";
}
}
myfile.close();
}
void sort(int table[], const int n) {
for (int i = 0; i < n; i++){
for (int j = 0; j < n - 1; j++) {
if (compare(table[j], table[j + 1]))
swap(&table[j], &table[j + 1]);
}
}
}
int main(){
int quantity;
int* tab;
ofstream outfile;
cout << "Enter number of element: ";
cin >> quantity;
tab = new int[quantity];
cout << "Element:\n\n" << endl;
for (int i = 0; i < quantity; i++){
int x = i;
cout << "#" << ++x << ":";
cin >> tab[i];
}
sort(tab, quantity);
cout << "The Sorted Elements are: ";
display(tab, quantity);
writeToFile(tab, quantity);
cout << endl;
getchar();
getchar();
//system("pause");
return 0;
}
in short, add this block to your code:
ofstream myfile;
myfile.open("example.txt");
for (int i = 0; i<n; i++) {
myfile << array[i];
if (i != n - 1){
myfile << ", ";
}
}
myfile.close();
You can use C++ fstream class, since you want to output, you can use ofstream here. You should just replace some "cout" with ofstream instance:
At the beginning of the code state it:
ofstream ofs("./sorted_elem.txt", ofstream::out);
When want to output:
ofs << "Sorted array:" << endl;
for(int i=0;i<n;i++)
{
ofs << a[i] << " , ";
}
ofs << endl;
In C++ you really want to use std::vector or some other nice container for storing arrays of numbers. For writing an array to file you need to open the file and individually write each element to the file (all untested).
#include <fstream>
int main()
{
std::ofstream fp("output.txt");
int data[5]; // todo: fill
for (unsitned i = 0; i < 5; ++i)
{
fp << data[i] << ' ';
}
}
And to read again:
#include <fstream>
int main()
{
std::ifstream fp("output.txt");
// todo: Determine the size of the array or guess it (don't guess it!)
unsigned array_size = 5;
int data[array_size];
int n = 0;
while (fp.good() && n < array_size) fp >> data[n++];
}
But because we are using C++, we can use std::vector:
#include <fstream>
#include <vector>
int main()
{
std::vector<int> me(5); // todo: fill
std::ofstream fp("output.txt");
for (size_t i = 0; i < me.size(); ++i) fp << me[i] << ' ';
// C++11: for (int d : me) fp << d << ' ';
}
And,
#include <fstream>
#include <vector>
int main()
{
std::ifstream fp("output.txt");
std::vector<int> data;
double buf;
while (fp >> buf) data.push_back(buf); // no longer need to guess
}
I think, the copy option was not demonstrated here so far.
Please check this code. (Assuming your vector is ready to use, I've skipped it).
The example uses a C-array and a vector. Please use the later in your code whenever possible. But however, for copy-function both work:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <fstream>
int main () {
int a[10]={0,1,2,3,4,5,6,7,8,9};
std::vector<int> v; for (int i=0; i<10; ++i)v.push_back(i*10); //0, 10, 20,...
std::ofstream fs_a( "c:/temp/out_a.txt" );
//store space separated
std::copy ( a, a+sizeof(a)/sizeof(a[0]), std::ostream_iterator<int>( fs_a, " ") );
//store coma-separated, as one-liner
std::copy ( v.begin(), v.end() ), std::ostream_iterator<int>( std::ofstream( "c:/temp/out_v.txt" ), ",") );
return 0;
}

Reading ints from .txt file to vector?

For some reason I am getting zero values in my vector when I try to read from a txt file.
Here is my code:
int main(){
ifstream read("problem13.txt");
vector<int> source;
int n;
while (read >> n){
source.push_back(n);
}
for (int i = 0; i < source.size(); i++)
cout << source[i];
cout << "Finished.";
}
The txt file is rather long but the format is:
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
91942213363574161572522430563301811072406154908250
23067588207539346171171980310421047513778063246676
Here is reading one by one:
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int main(){
ifstream read("e:\\problem13.txt");
vector<int> source;
char n;
while (read >> n){
source.push_back(n - '0');
}
for (int i = 0; i < source.size(); i++)
cout << source[i];
cout << endl << "Size: " << source.size() << endl << "Finished.";
}
But i recommend you reading line by line or if the file is no so big reading all in an std::string and process the string (reading from file is expensive).
In order to store each digit as an int, read each line and store it in a string. Then process each line.
int main(){
ifstream read("problem13.txt");
vector<int> source;
int n;
string line;
while (read >> line){
string::iterator iter = line.begin();
string::iterator end = line.end();
for ( ; iter != end; ++iter )
{
n = (*iter) - '0';
source.push_back(n);
}
}
for (int i = 0; i < source.size(); i++)
cout << source[i];
cout << "Finished.";
}