C++ Read from input file into struct array - c++

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;
}

Related

Read in Student info from a .txt file and then caluclate the average and find the letter grade

Im working on this program to read in students first, last name, and 5 grades and put the students info into a struct. From there Im trying to use other functions to find the average grade, letter grade, max grade, and minimum grade. Im having issues on the proper way to read in and store students info and then call upon students info within other functions to calculate average, letter grade, etc... My 'displayAverages' function doesn't list any names and the grades are huge negative numbers. IF you can help me (after your headache from looking at my code goes away that is) Id appreciate it.
#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <sstream>
using namespace std;
// Global variables
const int MAX_STUDENTS = 22;
const int MAX_GRADES = 5;
const string FILENAME = "NamesGrades.txt";
struct Student{
string name;
double grades[MAX_GRADES];
double average;
int max;
int min;
}students[MAX_STUDENTS];
char getLetterGrade(double grade);
void getData(Student &students)
{
ifstream fileIn;
int numStudents = 0;
fileIn.open(FILENAME.c_str());
if (fileIn.fail())
{
cout << "Could not open file" << endl;
system("PAUSE");
exit(1);
}
while (fileIn) {
for (int i = 0; i < MAX_STUDENTS; i++)
{
Student students;
getline(fileIn, students.name);
for (size_t i = 0; i < MAX_GRADES; i++)
{
fileIn >> students.grades[i];
}
return;
}
}
fileIn.close();
return;
}
void displayAverages(Student students) {
double total;
//double average;
int maxLength = 50;
cout << setprecision(1) << fixed << showpoint;
// Providing a header
cout << "\n\nGrade Averages\n";
cout << setw(maxLength + 1) << left << "Name" << setw(4) << right <<
"Average" << setw(6) << "Grade" << endl;
for (int i = 0; i < 22; i++)
{
cout << setw(maxLength + 1) << left << students.name;
total = 0;
for (int j = 0; j < MAX_GRADES; j++)
{
total += students.grades[i];
}
students.average = (double)total / MAX_GRADES;
cout << setw(7) << right << students.average << setw(6) <<
getLetterGrade(students.average) << endl;
}
}
char getLetterGrade(double grade) {
{
if (grade > 90) {
return 'A';
}
else if (grade > 80) {
return 'B';
}
else if (grade > 70) {
return 'C';
}
else if (grade > 60) {
return 'D';
}
else {
return 'F';
}
}
}
Let's take a look at your getData() function. It's defined as:
void getData(Student &students)
Since the return type is void, I'm guessing that you'll probably be passing in a Student and then modifying it in the function. However, you do:
Student students;
getline(fileIn, students.name);
Uh oh! This declares a new students that shadows the parameter students. So when you do students.name, you're talking about the local variable, not the parameter.
Kill that new declaration and things should work like you expected!
First thing - your code should have better structure!
void getData(Student &students)
{
ifstream fileIn;
int numStudents = 0;// you are not using this variable
fileIn.open(FILENAME.c_str());
if (fileIn.fail())
{
cout << "Could not open file" << endl;
system("PAUSE");
exit(1);
}
while (fileIn) {
for (int i = 0; i < MAX_STUDENTS; i++)//you should use auto here
{
Student students;//here you are making local object instead of changing the data off passed argument, you should get rid of this
getline(fileIn, students.name);
for (size_t i = 0; i < MAX_GRADES; i++)//you should use auto here
{
fileIn >> students.grades[i];
}
return;//you will return from you function after reading first student data so you should get rid of this
}
}
fileIn.close();
return;
}
After changes:
void getData(Student &students) {
ifstream fileIn;
fileIn.open(FILENAME.c_str());
if(fileIn.fail()) {
cout << "Could not open file" << endl;
system("PAUSE");
exit(1);
}
while(fileIn) {
for(auto i = 0; i < MAX_STUDENTS; i++) {
getline(fileIn, students.name);
for(auto i = 0; i < MAX_GRADES; i++)
fileIn >> students.grades[i];
}
}
fileIn.close();
}

Cpp program two find number of days between two given dates, consol CMD

//C++ program two find number of days between two given dates
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
// A date has day 'd', month 'm' and year 'y'
// 'h' hour , 'min' minute ; 'sec' second
struct Date
{
int d, m, y, h, min, sec;
};
Problem is in main :
int main(int argc, char** argv)
{
string line;
getline(cin, line);
int test = stoi(line);
unsigned int * tab = new unsigned int[test];
for (int i = 0; i <test; i++)
tab[i] = 0;
for (int i = 0; i<test; i++)
{
getline(cin, line);
int n1 = stoi(line);
int n2 = stoi(line);
tab[i] = getDifference(n1, n2); // HERE IS PROBLEM
}
for (int i = 0; i<test; i++)
{
cout << tab[i] << endl;
}
The error pops up:
No proper constructor to redirect "int" to "Date"
How to solve it?
My task is to download data through CMD, the first line is the number of tests, the next is 5 sets of dates to count the difference in days between them. Do you know how to tell the program that the first two lines are one set?
You'll need to read in each number separately into the members of a Date-object, and then compare Date-objects, not just single integers.
Strategy is to read in complete lines (e.g. "20 10 2017") and then use a stringstream for reading in the separate numbers:
#include <sstream>
struct Date
{
int d, m, y, h, min, sec;
};
ostream& operator << (ostream& o, Date & d) {
o << d.d << "/" << d.m << "/" << d.y;
return o;
};
int main() {
std::string line;
if (std::getline(std::cin,line)) {
int nrOfSets = 0;
stringstream reader(line);
reader >> nrOfSets;
int i=0;
Date previousDate;
while (i < nrOfSets && getline(cin,line)) {
Date d;
reader = stringstream(line);
if (! (reader >> d.d >> d.m >> d.y)) {
cout << "invalid input." << endl;
continue;
}
i++;
if (i > 1) { // already two dates entered?
cout << "calculating difference between " << d << " and " << previousDate << ":" << endl;
// your code: int difference = calcDifference(d, previousDate);
}
previousDate = d;
}
}
}
Input / Output:
2
20 10 2017
22 10 2017
calculating difference between 22/10/2017 and 20/10/2017:

How to move word in a circular motion in a string?

I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:

Multiple errors with function header, and overloaded functions

it's my first time working with classes and headers in C++ and I ran into these errors after putting together my code
function does not take 1 arguments // For all 4 functions
overloaded member function not found in 'Animals' // Also for all 4 fncs
syntax error: identifier 'fstream' // header file error
The program is designed to read and write to a file, while also doing searches and being able to manipulate the binary file. I'm pretty sure the error is in my declarations somewhere but I can't figure it out myself; any help is appreciated.
main.cpp
#include <iostream>
#include<iomanip>
#include <fstream>
#include"animals.h"
using namespace std;
int main()
{
Animals nA;
fstream animalFile;
int choice;
cout << setprecision(2) << fixed;
do
{
// Display the menu.
cout << "\n1. Add a new animal\n";
cout << "2. Remove an animal\n";
cout << "3. Search and display a animal\n";
cout << "4. Display all animals\n";
cout << "5. Exit\n";
do
{
cout << "Enter your choice (1-5): ";
cin >> choice;
} while (choice < 1 || choice > 5);
// Process the selection.
switch (choice)
{
// Choice 1 is to add an animal
case 1:
nA.addAnimal(animalFile);
break;
// Choice 2 is to remove an animal
case 2:
nA.removeAnimal(animalFile);
break;
// Choice 3 is to search and display 1 animal
case 3:
nA.searchAnimal(animalFile);
break;
// Choice 4 is to display all animals
case 4:
nA.displayAnimal(animalFile);
}
} while (choice != 5);
system("pause");
return 0;
}
Animals.h
#ifndef ANIMALS_H
#define ANIMALS_H
#include <string>
#include <iostream>
#include <fstream>
class Animals
{
private :
std::string name;
int age;
public :
//Default constructor
Animals();
//Create an animal object
Animals(std::string name, int age);
//Add a new animal record
void addAnimal(fstream &d);
//Remove an animal record
void removeAnimal(fstream &d);
//Displays an animal through a search
void searchAnimal(fstream &d);
//Display ALL animals
void displayAnimal(fstream &d);
};
#endif
Animals.cpp
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include "Animals.h"
using namespace std;
Animals::Animals()
{
name = "NULL";
age = 0;
}
Animals::Animals(std::string name, int age)
{
Animals *newAnimal = new Animals;
}
void Animals::addAnimal(fstream &d)
{
string userName;
int userAge = 0;
int stringRemainder;
int record;
const int RECORD_SIZE = 40;
//Collecting user input
do
{
std::cout << "Please enter your animal name: ";
std::cin >> userName;
std::cout << "\n";
} while (sizeof(userName) > 30);
do
{
std::cout << "Please enter your animal age: ";
std::cin >> userAge;
std::cout << "\n";
} while (userAge <= 0 || !isdigit(userAge));
//Fixing length of string
stringRemainder = 30 - sizeof(userName);
//Finds record number based on position
record = (d.tellg() % RECORD_SIZE) + 1;
//Writing to file
d.close();
d.open("animals.txt", std::ios_base::app | ios::binary);
d << record << "";
d << userName;
for (int i = 0; i < stringRemainder; i++)
{
d << "";
}
d << userAge << "\n";
d.close();
}
void Animals::removeAnimal(fstream &d)
{
int recordNumber = 0;
const int RECORD_SIZE = 40;
char recordBuffer[RECORD_SIZE];
d.open("animals.txt", ios::out| ios::in |ios::binary);
//Collecting user input
do
{
cout << "Enter the record of the animal to be removed: ";
cin >> recordNumber;
} while (recordNumber <= 0 || !isdigit(recordNumber));
// move pointer to desired position, and overwrite!
d.seekp((recordNumber-1) * RECORD_SIZE);
d.write(recordBuffer, RECORD_SIZE);
d.close();
}
void Animals::searchAnimal(fstream &d)
{
int userRecord = 0;
char displayRecord[2];
const int RECORD_SIZE = 40;
char fileOutput[RECORD_SIZE];
string displayInfo;
char displayName[RECORD_SIZE];
char displayAge[2];
int i,k;
int j = 0;
d.open("animals.txt", ios::out | ios::binary);
//Getting user input
do
{
cout << "Enter the record of the animal to be diplayed: ";
cin >> userRecord;
} while (userRecord <= 0 || !isdigit(userRecord));
//Moving pointer position to searched value
d.seekp((userRecord - 1) * RECORD_SIZE);
//Gets data from file, stores into displayInfo
getline(d, displayInfo);
d.close();
//Entering file data into diplay variables,
//value 'i' increments through entire displayInfo array
for (i = 0; isdigit(displayInfo[i]); i++)
{
displayRecord[i] = displayInfo[i];
}
//New sentinel for ONLY string cap including buffer
k = i + 30;
for (i; i < k; i++)
{
displayName[j] = displayInfo[i];
j++;
}
//Finishes off last of the displayInfo array
for (i; i < sizeof(displayInfo); i++) {
displayAge[i] = displayInfo[i];
}
//Prints the data for user
cout << "For record number: " << userRecord << "\n";
cout << "Animal: ";
for (int i = 0; i < strlen(displayName); i++)
{
cout << displayName[i];
}
cout << "\n";
cout << "Age: ";
for (int i = 0; i < strlen(displayAge); i++)
{
cout << displayAge[i];
}
cout << "\n";
}
//Mostly copied from above function, displays ALL animals
void Animals::displayAnimal(fstream &d)
{
int userRecord = 0;
char displayRecord[2];
const int RECORD_SIZE = 40;
char fileOutput[RECORD_SIZE];
string displayInfo;
char displayName[RECORD_SIZE];
char displayAge[2];
int numberOfRecords;
int i, k;
int j = 0;
int q = 0;
d.open("animals.txt", ios::out | ios::in | ios::binary);
d.seekg(0, d.end);
numberOfRecords = d.tellg() % RECORD_SIZE;
d.seekg(0, d.beg);
for (int q; q < numberOfRecords; q++) {
d.seekp(q * RECORD_SIZE);
//Gets data from file, stores into displayInfo
getline(d, displayInfo);
//Entering file data into diplay variables,
//value 'i' increments through entire displayInfo array
for (i = 0; isdigit(displayInfo[i]); i++)
{
displayRecord[i] = displayInfo[i];
}
//New sentinel for ONLY string cap including buffer
k = i + 30;
for (i; i < k; i++)
{
displayName[j] = displayInfo[i];
j++;
}
//Finishes off last of the displayInfo array
for (i; i < sizeof(displayInfo); i++) {
displayAge[i] = displayInfo[i];
}
//Prints the data for user
cout << "For record number: " << userRecord << "\n";
cout << "Animal: ";
for (int i = 0; i < strlen(displayName); i++)
{
cout << displayName[i];
}
cout << "\n";
cout << "Age: ";
for (int i = 0; i < strlen(displayAge); i++)
{
cout << displayAge[i];
}
cout << "\n\n";
}
d.close();
}
The headers <iostream> and <fstream> bring their symbols into the std namespace, so any reference to these symbols in the header need to be fully qualified; e.g. std::fstream. Also, you might want to include <iosfwd> in your headers instead - this minimizes the compiler time cost of importing the header, assuming that the header only uses reference to the symbols mentioned in the iostream header.
You should use ifstream for read files and ofstream for write files.
And in header file, you should use std::ifstream & d or std::ofstream & d in argument of 4 functions.

Retrieve the first value from a map

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;
}