Importing times from a txt file in c++ - c++

I have this call log consisting of day time and duration data in a file:
Mo 12:30 16
Tu 7:15 10
We 9:10 20
Th 15:34 6
Fr 13:12 8
I want to store these data into variables so but i'm having trouble because of the colons.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inputfile;
string day;
double time;
int hours;
string semicolon;
int minutes;
int timeSpent;
inputfile.open("Data.txt");
inputfile >> day;
cout << day << endl;
inputfile >> hours;
cout << hours << endl;
inputfile >> semicolon;
cout << semicolon << endl;
inputfile >> minutes;
cout << minutes << endl;
inputfile >> timeSpent;
cout << timeSpent << endl;
return 0;}

C++11 has get_time and put_time for this, with a small tweak to your date format (at least three letters for days, hours and minutes must have leading zeros if less than 10) it's as easy as writing:
#include <iostream>
#include <iomanip>
int main()
{
std::tm t;
int duration;
while (std::cin >> std::get_time(&t, "%a %R") >> duration)
std::cout << std::put_time(&t, "%a %R") << ' ' << duration << '\n';
}
Your input would be as follows:
Mon 12:30 16 Tue 07:15 10 Wed 09:10 20 Thu 15:34 6 Fri 13:12 8

Related

How can I subtract two inputted dates (Years, Months, Days) taking Leap Years into consideration

I have been trying to figure out how to accurately subtract one date from another in C++. Both will be received through user input. I thought that by creating a class, along with the use of <ctime>, I would be able to do this but I have yet to find how to do so while taking Leap years into consideration, which would be the cause for the loss of accuracy that it might have.
Here is how I was approaching the task:
#include "pch.h"
#include <iostream>
#include <ctime>
using namespace std;
class Year {
private:
struct tm date3;
struct tm date2;
struct tm date;
int FirstYear, SecondYear;
int FirstMonth, SecondMonth;
int FirstDay, SecondDay;
public:
int DateCalculus(struct tm* date, struct tm* date2);
void ResultShown();
};
int Year::DateCalculus(struct tm* date, struct tm* date2) {
struct tm date3;
date3.tm_year = date->tm_year - date2->tm_year;
date3.tm_mon = date->tm_mon - date2->tm_mon;
date3.tm_mday = date->tm_mday - date2->tm_mday;
}
void Year::ResultShown() {
cout<< date3;
}
int main() {
struct tm Date = { 0, 0, 12 };
struct tm Date2 = { 0, 0, 12 };
int Firstyear, SecondYear;
int Firstmonth, SecondMonth;
int Firstday, SecondDay;
cin >> Firstday; cout << "Day 1 " << endl;
cin >> Firstmonth; cout << "Month 1 " << endl;
cin >> Firstyear; cout << "Year 1 " << endl;
cin >> SecondDay; cout << "Day 2 " << endl;
cin >> SecondMonth; cout << "Month 2 " << endl;
cin >> SecondYear; cout << "Year 2 " << endl;
Date.tm_year = Firstyear;
Date.tm_mon = Firstmonth;
Date.tm_mday = Firstday;
Year::DateCalculus(&Date, &Date2);
cout << asctime(&Date2) << std::endl;
return 0;
}

Subtracting an arbitrary date from the current date C++

I'm brand new to C++. In my Programming I class, I've been given the following assignment as a midterm:
-Calculate how many days you have been alive
(epoch time from 01/01/1970 stored by seconds)
-Command Line Args for Birth Year, Birth Month, Birth Day
Now, I've already figured out the function itself for actually subtracting two dates from each other, and I've figured out how to grab the current date and stick it in that function. The problem I'm having is how to get the user's entered date and send that to the function.
I've been playing with a "test" piece of code to get this to work, unfortunately when I try to compile this I just get a MOUNTAIN of errors that I don't understand at all, so I'm clearly doing something wrong.
#include <iostream>
#include <ctime>
using namespace std;
struct tm a(int year, int month, int day)
{
struct tm birth {0};
cin >> year >> endl;
cin >> month >> endl;
cin >> day >> endl;
birth.tm_year = year - 1900;
birth.tm_mon = month;
birth.tm_mday = day;
return birth;
}
int main()
{
int year, month, day;
cout << "Enter a year, month, and day: " << endl;
cin >> year >> month >> day >> endl;
tm a(year, month, day);
time_t x = mktime(&a);
time_t y = time(0);
if ( x != (time_t)(-1) && y != (time_t)(-1) )
{
double difference = difftime(y, x) / (60 * 60 * 24);
cout << ctime(&x);
cout << ctime(&y);
cout << "difference = " << difference << " days" << endl;
}
return 0;
}
I've tried googling some of these errors, and the results I'm seeing keep talking about "pointers". I have no clue what pointers are, and flipping through our textbook, it looks like something that's about three or four chapters ahead of where we are now. I tried asking my professor about this the other day, and he just sort of giggled and said something to the effect of "Well yeah, that's the point of the midterm." I don't understand if that means I'm supposed to figure out pointers on my own or if I'm not supposed to use them.
I'm trying to get a year, month, and day from arguments entered by the user at the point of execution and stick them into a struct tm so that my function at the bottom will work.
EDIT: I figured out that I am trying to use the struct like a function, which is wrong. I have made the following changes:
#include <iostream>
#include <ctime>
using namespace std;
struct tm bday(int year, int month, int day)
{
struct tm r {0};
r.tm_year = year - 1900;
r.tm_mon = month;
r.tm_mday = day;
return r;
}
int main()
{
int year, month, day;
cout << "Enter a year, month, and day: " << endl;
cin >> year >> endl;
cin >> month >> endl;
cin >> day >> endl;
struct tm a = bday(year, month, day);
time_t x = mktime(&a);
time_t y = time(0);
if ( x != (time_t)(-1) && y != (time_t)(-1) )
{
double difference = difftime(y, x) / (60 * 60 * 24);
cout << ctime(&x);
cout << ctime(&y);
cout << "difference = " << difference << " days" << endl;
}
return 0;
}
Now getting the following errors when compiling:
filename.cpp:22:17: error: no match for 'operator>>'
filename.cpp:23:18: error: no match for 'operator>>'
filename.cpp:24:16: error: no match for 'operator>>'
This is not correct:
cin >> year >> endl;
You cannot read anything into endl. You probably confused input with output where std::cout << x << std::endl; is a common pattern. However, as a sidenote, you dont need endl after each line for output either. endl not only adds a newline character, but also flushes the stream. If you just want to start a new line then use \n only.

How convert string to datetime c++?

string s = v[2];
string result = s.substr(s.find_last_of("modify=") + 1, 14);
cout << result;//output MDTM boost.txt 20150911115551
i want convert like this YYYY-MM-DD HH:MM
To access date and time related functions and structures, you would need to include header file in your C++ program.
There are four time-related types: clock_t, time_t, size_t, and tm. The types clock_t, size_t and time_t are capable of representing the system time and date as some sort of integer.
The structure type tm holds the date and time in the form of a C structure having the following elements:
struct tm {
int tm_sec; // seconds of minutes from 0 to 61
int tm_min; // minutes of hour from 0 to 59
int tm_hour; // hours of day from 0 to 24
int tm_mday; // day of month from 1 to 31
int tm_mon; // month of year from 0 to 11
int tm_year; // year since 1900
int tm_wday; // days since sunday
int tm_yday; // days since January 1st
int tm_isdst; // hours of daylight savings time
}
Considering that you have the data string in the following format "YYY-MM-DD HH:MM:SS", the subsequent code below show how to convert the string in a date structure:
#include <iostream>
#include <ctime>
#include <string.h>
#include <cstdlib>
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
char date[] = "2012-05-06 21:47:59";
tm *ltm = new tm;
char* pch;
pch = strtok(date, " ,.-:");
ltm->tm_year = atoi(pch); //get the year value
ltm->tm_mon = atoi(strtok(NULL, " ,.-:")); //get the month value
ltm->tm_mday = atoi(strtok(NULL, " ,.-:")); //get the day value
ltm->tm_hour = atoi(strtok(NULL, " ,.-:")); //get the hour value
ltm->tm_min = atoi(strtok(NULL, " ,.-:")); //get the min value
ltm->tm_sec = atoi(strtok(NULL, " ,.-:")); //get the sec value
// print various components of tm structure.
cout << "Year: "<< ltm->tm_year << endl;
cout << "Month: "<< ltm->tm_mon<< endl;
cout << "Day: "<< ltm->tm_mday << endl;
cout << "Time: "<< ltm->tm_hour << ":";
cout << ltm->tm_min << ":";
cout << ltm->tm_sec << endl;
delete ltm;
return 0;
}
Output:
Year: 2012
Month: 5
Day: 6
Time: 21:47:59

C++ String DD:HH:MM:SS to integer data types

My question is simple. Given a string that represents time as DD:HH:MM:SS, with colons, how can I strip this into 4 separate data types of int?
Thanks so much
You can use the stringstream to parse the text like so:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string time = "01:23:45:67";
int secs;
int mins;
int hours;
int days;
char extra;
std::stringstream ss;
ss << time;
ss >> days >> extra
>> hours >> extra
>> mins >> extra
>> secs;
std::cout << days << ":" << hours << ":" << mins << ":" << secs;
}

How to read in a set of values from a text file, then go to the next line and do the same

Im trying to read a list like this one
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
and store each value into a a separate variable. The names are strings, and the other numbers are floats and an int. I can get the data from one line so far, but I dont know how to go onto the next line and do the same. Here is my code so far.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream employees;
string lastname, firstname, lastname1, firstname1, lastname2, firstname2;
float base, sales, base1, sales1, base2, sales2;
int years, years1, years2;
employees.open("employees.txt");
while (employees)
{
employees >> lastname >> firstname >> base >> sales >> years;
I want to keep it as simple as possible, I dont know user defined functions, arrays, or vectors at all yet. So is there a simple function that will just end the line at years; and go to the next line and carry on?
Thanks.
Use an array. Whenever you end up with "I want to add a number to this variable because I want more than one", if the number reaches more than 2, then you should really use an array (unless very special cases).
You may also want to use a struct to store your different values (firstname, lastname, base, sales and years) - that way, you only get a single array, rather than several different arrays.
Since this is C++, arrays means vector. In other words:
struct employee
{
string firstname, lastname;
float base, sales;
int years;
};
vector<employee> emp_table;
employee e;
while (employees >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years)
{
emp_table.push_back(e);
}
Note I put the input of employees as the while-condition. This avoids an extra loop iteration and "pushing back" a second copy of the last entry when you have reached end of file.
There are many ways in C++ to accomplish what you are trying to do. One approach that allows for data validation is to use the std::getline function to read the file one line at a time and then use a std::stringstream to parse the data.. This allows you to validate the data and continue processing if the data on a line is malformed.
[As Mats noted you can use a data structure and std::vector to make storing and managing the data easier.]
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
struct employee
{
std::string firstname;
std::string lastname;
float base;
float sales;
int years;
};
int main()
{
std::ifstream employeeFile;
employeeFile.open("employees.txt");
std::string tmpLine;
std::vector<employee> employeeTable;
// read in an entire line at a time
while(std::getline(employeeFile, tmpLine))
{
// Place the input line into a stream that reads from
// a string instead of a file.
std::stringstream inputLine(tmpLine);
// Try parsing the data. The ! operator is used here to check
// for errors. Since we expect the data to be in a specific format
// we want to be able to handle situations where the input line
// may be malformed. For example, encountering a string where
// a number should be.
employee e;
if(!(inputLine >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years))
{
// ... error parsing input. Report the error
// or handle it in some other way.
continue; // keep going!
}
// Add to the vector
employeeTable.push_back(e);
}
return 0;
}
You can use getline inside your loop to retrieve each line and then use it with a stringstream
Something like:
string line;
while(getline(employees,line))
{
//doSomething
}
If you can't use arrays to store them easily, you can put a counter to know at which line you're at, but this is very repetitive, and the number of lines in your file cannot vary:
string line;
for (int count = 1 ; count <= 3 ; count++)
{
getline(employees,line);
istringstream iss(line);
if (count == 1)
{
iss >> lastname >> firstname >> base >> sales >> years;
}
else if (count == 2)
{
iss >> lastname1 >> firstname1 >> base1 >> sales1 >> years1;
}
else if (count == 3)
{
iss >> lastname2 >> firstname2 >> base2 >> sales2 >> years2;
}
}
Opening and reading a file properly is harder than learning what an array is. If you don't use an array you have to use too many variables to hold all your data, and you have to repeatedly write the code to read from the file, rather than writing it once in a loop.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstNames[3];
string lastNames[3];
float heights[3];
float weights[3];
int ages[3];
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
int count = 0;
while (infile >> firstNames[count]
>> lastNames[count]
>> heights[count]
>> weights[count]
>> ages[count] )
{
++count;
}
infile.close();
for (int i = 0; i<count; ++i) {
cout << firstNames[i] << " "
<< lastNames[i] << " "
<< heights[i] << " "
<< weights[i] << " "
<< ages[i] << " " << endl;
}
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Compare to this disaster:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstName0,firstName1, firstName2;
string lastName0, lastName1, lastName2;
float height0, height1, height2;
float weight0, weight1, weight2;
int age0, age1, age2;
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
infile >> firstName0 >> lastName0 >> height0 >> weight0 >> age0;
infile >> firstName1 >> lastName1 >> height1 >> weight1 >> age1;
infile >> firstName2 >> lastName2 >> height2 >> weight2 >> age2;
infile.close();
cout << firstName0 << " "
<< lastName0 << " "
<< height0 << " "
<< weight0 << " "
<< age0 << endl;
cout << firstName1 << " "
<< lastName1 << " "
<< height1 << " "
<< weight1 << " "
<< age1 << endl;
cout << firstName2 << " "
<< lastName2 << " "
<< height2 << " "
<< weight2 << " "
<< age2 << endl;
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Look at all the code you have to repeat.
Note that when you use an array, the variable names become firstNames[0] (v. firstName0), lastNames[0] (v. lastName0), etc., and firstNames[1] (v. firstName1) and lastNames[1] (v. lastName0).