我正在制作一个统计数据收集器,它可以读取音乐播放器的日志,并让用户显示最常被播放的十个等。作为一个菜鸟项目。
日志中的一行看起来像是:“20:42:03开始E:\ ROTATION \ A \HåkanLidbo - Dammlunga.mp3”
我已经使用ifstream和getline将它放在一个字符串中。
然后使用
创建字符串的字符数组const char *charveqtur = newline.c_str();
然后我试着用sscanf排序:
sscanf (charveqtur, "%d:%d:%d\tstart\t%s", &this->hour, &this->minute, &this->second, &this->filename);
问题是文件名是在第一个空格处剪切的。我也尝试过使用istringstream,但到目前为止还没有突破。
这是最方便的方法吗?感谢。
答案 0 :(得分:2)
您可以使用某些输入流来读取第一个整数和冒号,并且因为文件名是最后一个实体,您可以使用std::getline
。但是,即使您的文件名不是最后一部分,请注意std::getline
是一个非常通用的函数,可以接受任何分隔符。
更高级的方法是为文件名定义自己的类型并在其上重载operator>>(std::istream &, T const &)
。
以下是使用std::getline
和stringstream
进行基本诊断和重新格式化的完整示例:
#include <sstream> // for istringstream
#include <iostream> // for cout and cerr
#include <iomanip> // for setprecision
#include <cmath>
bool read (std::string const &line) {
char c = 0;
double length;
double rating;
std::string title;
std::istringstream ss;
ss.str (line);
ss >> length;
if (!ss.good()) { std::cerr << "invalid length\n"; return false; }
if (ss.get()!=':') { std::cerr << "expected colon\n"; return false; }
ss >> rating;
if (!ss.good()) { std::cerr << "invalid rating\n"; return false; }
if (ss.get()!=':') { std::cerr << "expected colon\n"; return false; }
std::getline (ss, title);
double sink;
std::cout << title << " ("
<< int(length) << ':' << 60*std::modf (length,&sink)
<< " min), your rating: " << rating << '\n';
return true;
}
int main () {
read ("30.25:5:Vivaldi - The four seasons.ogg");
read ("3.5:5:Cannibal Corpse - Evisceration Plague.ogg");
read ("meh");
return 0;
}
输出:
Vivaldi - The four seasons.ogg (30:15 min), your rating: 5
Cannibal Corpse - Evisceration Plague.ogg (3:30 min), your rating: 5
invalid length
重要:解析时,您正在接近安全风险。始终保持清醒和理智,尽可能使用经过测试和验证的库。这也意味着您不使用sscanf
,不是类型安全,容易出错,有时很难做对}强> 的
如果您使用C ++,请不要使用C,并且使用正确,iostreams比printf / scanf + co更方便。
答案 1 :(得分:0)
你可以做一些像
这样的事情int lastpos = 0;
if sscanf (charveqtur, "%d:%d:%d\tstart\t%n", &this->hour,
&this->minute, &this->second,
&lastpos) > 3 && lastpos >0) {
std::string filename = newline.substr(lastpos);
/* do something with filename */
}