问题
I am writing a c++ prgram and have to read some data from a .txt
file.the format looks like the following:
"name gender DD/MM/YYYY HH:MM:SS
"
I know how to read a .txt
file and cin the words one by one, but i dont know how to deal with the symbols "/
" or ":
".
I have to compare the ages of two person.
Please help!
回答1:
Aside from the easiest way with sscanf
, like Jerry describes, it's also possible with iostreams. Just read the data you want from the file, until you hit a seperator, and discard that one into a dummy char
:
char dummy;
myfile >> first_name >> last_name >> day >> dummy >> month >> dummy ... // and so on.
回答2:
This is one of those tasks that's really a lot easier with something like sscanf:
sscanf(input_string,
"%s %s %d/%d/%d %d:%d:%d",
name, gender, &day, &month, &year, &hour, &minute, &second);
You can use iostreams, but not nearly as easily. You have a couple of basic choices. One is to use a locale
with ':' and '/' defined as whitespace, which will let you just stream in the values and ignore the separators (but won't warn you about some types of mis-formatting, such as substituting a '/' for a ':' or vice versa.
Another possibility is to read those characters explicitly, and (if you choose) validate them by comparing each separator to what you expect. If you're really serious about assuring the data is in the expected format, this is probably the way to go.
回答3:
Look at the following link. It will solve your problem.
- Reading Every Characters In A Text File
回答4:
In C you would use sscanf() or more directly, fscanf() but those functions are considered poor style in C++.
I'd suggest something like this:
struct SData
{
std::string sName;
std::string sGender;
int nDay;
int nMon;
int nYear;
int nHour;
int nMin;
int nSec;
};
bool ReadRecord(std::istream &istr, SData &data)
{
istr >> data.sName
>> data.sGender
>> data.nDay;
istr.ignore(1); // '/'
istr >> data.nMon;
istr.ignore(1); // '/'
istr >> data.nYear
>> data.nHour;
istr.ignore(1); // ':'
istr >> data.nMin;
istr.ignore(1); // ':'
istr >> data.nSec;
return istr.good();
}
Update
The following example simplifies use by excluding the struct
#include <iostream>
#include <fstream>
#include <string>
bool ReadRecord(std::istream &istr,
std::string &sName,
std::string &sGender,
int &nDay,
int &nMon,
int &nYear,
int &nHour,
int &nMin,
int &nSec)
{
istr >> sName
>> sGender
>> nDay;
istr.ignore(1); // '/'
istr >> nMon;
istr.ignore(1); // '/'
istr >> nYear
>> nHour;
istr.ignore(1); // ':'
istr >> nMin;
istr.ignore(1); // ':'
istr >> nSec;
return istr.good();
}
int main()
{
std::string sName0, sGender0, sName1, sGender1;
int nDay0, nMon0, nYear0, nDay1, nMon1, nYear1;
int nHour0, nMin0, nSec0, nHour1, nMin1, nSec1;
const char szFileName[] = "MyData.txt";
std::ifstream istr(szFileName);
if (!istr.is_open())
{
std::cerr << "Cannot open file\n";
return 1;
}
if (!ReadRecord(istr, sName0, sGender0, nDay0, nMon0, nYear0, nHour0, nMin0, nSec0))
{
std::cerr << "Cannot read file\n";
return 1;
}
if (!ReadRecord(istr, sName1, sGender1, nDay1, nMon1, nYear1, nHour1, nMin1, nSec1))
{
std::cerr << "Cannot read file\n";
return 1;
}
std::string sYounger;
if (nYear0 == nYear1)
{
if (nMon0 == nMon1)
{
if (nDay0 == nDay1)
{
if (nHour0 == nHour1)
{
if (nMin0 == nMin1)
{
if (nSec0 > nSec1)
{
sYounger = sName0;
}
else if (nSec0 < nSec1)
{
sYounger = sName1;
}
}
else if (nMin0 > nMin1)
{
sYounger = sName0;
}
else if (nMin0 < nMin1)
{
sYounger = sName1;
}
}
else if (nHour0 > nHour1)
{
sYounger = sName0;
}
else if (nHour0 < nHour1)
{
sYounger = sName1;
}
}
else if (nDay0 > nDay1)
{
sYounger = sName0;
}
else if (nDay0 < nDay1)
{
sYounger = sName1;
}
}
else if (nMon0 > nMon1)
{
sYounger = sName0;
}
else if (nMon0 < nMon1)
{
sYounger = sName1;
}
}
else if (nYear0 > nYear1)
{
sYounger = sName0;
}
else if (nYear0 < nYear1)
{
sYounger = sName1;
}
if (sYounger.empty())
{
std::cout << "The ages are the same\n";
}
else
{
std::cout << sYounger << "is younger\n";
}
return 0;
}
回答5:
Inspired by How to split a string? I decided to take a shot.
Given the data below:
File: dates.txt
james male 01/02/1987 04:01:02
jerry male 11/06/1965 08:03:04
jon male 21/10/1977 12:05:06
The following application parses each line of the file and stores the information on a temporary object named dude and later adds it to people_list . The parsing of date/time is done through strtok, which is nice function to split a string into tokens. At the end, we iterate on the vector printing what was found.
#include <iostream>
#include <string>
#include <fstream>
#include <iterator>
#include <sstream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
typedef struct _time
{
int h; // hour
int m; // minute
int s; // seconds
} Time;
typedef struct _date
{
int y; // year
int m; // month
int d; // day
} Date;
class Person
{
public:
string name;
string gender;
Time time;
Date date;
};
int main()
{
ifstream in("dates.txt");
vector<Person> people_list;
string line;
while (getline(in,line))
{
if (line.empty())
{
continue;
}
vector<string> tmp;
istringstream iss(line);
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter<vector<string> >(tmp));
// Parsing name and gender (easy)
Person dude;
dude.name = tmp[0];
dude.gender = tmp[1];
// Date
char delim_slash[] = "/";
char* result = NULL;
result = strtok(const_cast<char*>(tmp[2].c_str()), delim_slash);
dude.date.d = atoi(result);
result = strtok(NULL, delim_slash);
dude.date.m = atoi(result);
result = strtok(NULL, delim_slash);
dude.date.y = atoi(result);
// Time
char delim_colon[] = ":";
result = strtok(const_cast<char*>(tmp[3].c_str()), delim_colon);
dude.time.h = atoi(result);
result = strtok(NULL, delim_colon);
dude.time.m = atoi(result);
result = strtok(NULL, delim_colon);
dude.time.s = atoi(result);
people_list.push_back(dude);
}
for (int i = 0; i < people_list.size(); i++)
{
cout << "Name: " << people_list[i].name << endl;
cout << "Gender: " << people_list[i].gender << endl;
cout << "Date: " << people_list[i].date.d << "/" <<
people_list[i].date.m << "/" <<
people_list[i].date.y << endl;
cout << "Time: " << people_list[i].time.h << ":" <<
people_list[i].time.m << ":" <<
people_list[i].time.s << endl << endl;
}
}
Outputs:
Name: james
Gender: male
Date: 1/2/1987
Time: 4:1:2
Name: jerry
Gender: male
Date: 11/6/1965
Time: 8:3:4
Name: jon
Gender: male
Date: 21/10/1977
Time: 12:5:6
来源:https://stackoverflow.com/questions/5447002/how-to-read-a-birthday-with-symbols-and-from-a-txt-file