1

私は、音楽プレーヤーのログを読み取り、ユーザーが最も再生されたトップ 10 などを表示できる統計コレクターを noob プロジェクトとして作成しています。

ログの行は次のようになります: "20:42:03 start E:\ROTATION\A\Håkan Lidbo - 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 を使用してみましたが、これまでのところ突破口はありません。

これを行う最も便利な方法はどれですか? ありがとう。

4

2 に答える 2

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

重要: 解析中は、セキュリティ リスクに近づきます。常に意識的で賢明であり、可能な場合はテスト済みで実証済みのライブラリを使用するようにしてください。これは、 typesafeではなく、エラーが発生しやすく、時には正しく取得するのが難しい を使用しないことsscanfも意味します。

C++ がある場合は C を使用しないでください。正しく使用すると、iostream は printf/scanf+co よりもさらに便利です。

于 2011-11-21T14:23:33.453 に答える
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 */
}
于 2011-11-21T14:24:10.097 に答える