1

これは簡単な作業かもしれませんが、現時点では、これを簡単な方法で行う方法がまったくわかりません。次のような状況があります。3D プログラム Cinema 4D のスクリプト言語である COFFEE で書かれたスクリプトがあります。このスクリプトは、次の形式の位置データをテキスト ファイル (この場合は rtf ですが、.txt の場合もあります) に書き込みます。

0  0.0  471.2  0.0
1  0.0  470.5  0.0
2  0.0  468.8  0.0
3  0.0  465.9  0.0
4  0.0  461.9  0.0
5  0.0  456.8  0.0
6  0.0  450.5  0.0
7  0.0  443.2  0.0
8  0.0  434.8  0.0
9  0.0  425.2  0.0

フレーム、X、Y、Z。

次に、この位置データを次の形式に変換する必要があります。

Transform   Position
    Frame   X pixels    Y pixels    Z pixels    
    0   0.0    471.2    0.0 
    1   0.0    470.5    0.0 
    2   0.0    468.8    0.0 


End of Keyframe Data

ここでは実際には表示されませんが、ここにはスペースがありません。すべてがタブで区切られています (実際にタブを表示するには、それをメモ帳にコピーしてください)。すべての数字の間にタブを入れることが重要です。スペースを入れることはできますが、常に 1 つのタブ文字が必要です。したがって、最も重要な部分は、最初のデータセットからこれらの数値を取得し、プログラムにすべての数値の間に \t を追加させるにはどうすればよいかということです。

スクリプト内でこれを実行しようとしましたが、位置の間にいくつかのスペースではなくタブを使用すると、スクリプトが失敗します。かなり検索しましたが、これに対する良い解決策が見つかりませんでした。私は C++ と小さなバッチ スクリプトに精通していますが、別の言語の基本を学ばなければならない場合でも、すべてのソリューションに満足しています。

私は C++ で方法を見つけようとしましたが、思いついた方法では n 行をフォーマットできず、すべてが複雑になりました。フレーム/ラインの数は毎回変わるので、ライン数が固定されることはありません。

4

3 に答える 3

2

正規表現を使用したさらに別の例

#include <fstream>
#include <iostream>
#include <regex>
#include <algorithm>
int main()
{
    using namespace std;

    ifstream inf("TextFile1.txt");
    string data((istreambuf_iterator<char>(inf)), (istreambuf_iterator<char>()));

    regex reg("([\\d|\.]+)\\s+([\\d|\.]+)\\s+([\\d|\.]+)\\s+([\\d|\.]+)");  
    sregex_iterator beg(data.cbegin(), data.cend(), reg), end;

    cout << "Transform\tPosition" << endl;
    cout << "\tFrame\tX pixels\tY pixels\tZ pixels" << endl;
    for_each(beg, end, [](const smatch& m) {
        std::cout << "\t" << m.str(1) << "\t" << m.str(2) << "\t" << m.str(3) << "\t" << m.str(4) << std::endl;
    });
    cout << "End of Keyframe Data" << endl;
}
于 2012-07-15T02:29:13.887 に答える
2

このようなものがうまくいくかもしれません。数値の特別な書式設定は行っていないため、必要に応じて追加する必要があります。不正な形式の入力ファイルが心配な場合は、行に十分な数字がないなど、それを防ぐために追加のエラー チェックを追加する必要があります。

#include <fstream>
#include <iostream>
#include <vector>

bool Convert(const char* InputFilename, const char* OutputFilename)
{
    std::ifstream InFile(InputFilename);
    if(!InFile)
    {
        std::cout << "Could not open  input file '" << InputFilename << "'" << std::endl;
        return false;
    }

    struct PositionData
    {
        double FrameNum;
        double X;
        double Y;
        double Z;
    };
    typedef std::vector<PositionData> PositionVec;

    PositionVec Positions;
    PositionData Pos;
    while(InFile)
    {
        InFile >> Pos.FrameNum >> Pos.X >> Pos.Y >> Pos.Z;
        Positions.push_back(Pos);
    }

    std::ofstream OutFile(OutputFilename);
    if(!OutFile)
    {
        std::cout << "Could not open output file '" << OutputFilename << "'" << std::endl;
        return false;
    }

    OutFile << "Transform\tPosition\n\tFrame\tX pixels\tY pixels\tZ pixels" << std::endl;
    for(PositionVec::iterator it = Positions.begin(); it != Positions.end(); ++it)
    {
        const PositionData& p(*it);
        OutFile << "\t" << p.FrameNum << "\t" << p.X << "\t" << p.Y << "\t" << p.Z << std::endl;
    }
    OutFile << "End of Keyframe Data" << std::endl;
    return true;
}

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        std::cout << "Usage: convert <input filename> <output filename>" << std::endl;
        return 0;
    }
    bool Success = Convert(argv[1], argv[2]);

    return Success;
}
于 2012-07-15T00:40:09.843 に答える
1

興味がある場合は、Python スクリプトの例。

#!c:/Python/python.exe -u
# Or point it at your desired Python path
# Or on Unix something like: !/usr/bin/python

# Function to reformat the data as requested.
def reformat_data(input_file, output_file):

    # Define the comment lines you'll write.
    header_str = "Transform\tPosition\n"
    column_str = "\tFrame\tX pixels\tY pixels\tZ pixels\n"
    closer_str = "End of Keyframe Data\n"

    # Open the file for reading and close after getting lines.
    try:
        infile = open(input_file)
    except IOError:
        print "Invalid input file name..."
        exit()

    lines = infile.readlines()
    infile.close()

    # Open the output for writing. Write data then close.
    try:
        outfile = open(output_file,'w')
    except IOError:
        print "Invalid output file name..."
        exit()

    outfile.write(header_str)
    outfile.write(column_str)

    # Reformat each line to be tab-separated.
    for line in lines:
        line_data = line.split()
        if not (len(line_data) == 4):
            # This skips bad data lines, modify behavior if skipping not desired.
            pass 
        else:
            outfile.write("\t".join(line_data)+"\n")

    outfile.write(closer_str)
    outfile.close()

#####
# This below gets executed if you call
# python <name_of_this_script>.py
# from the Powershell/Cygwin/other terminal.
#####
if __name__ == "__main__":
    reformat_data("/path/to/input.txt", "/path/to/output.txt")
于 2012-07-16T02:55:44.537 に答える