Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 向文本文件中的空行添加时间戳_C++_File_Timestamp - Fatal编程技术网

C++ 向文本文件中的空行添加时间戳

C++ 向文本文件中的空行添加时间戳,c++,file,timestamp,C++,File,Timestamp,给定文本文件中的以下文本,对于每一个空行,我想取下一行的时间戳,减去0.8,然后把它放在该空行中 [00:00.00] [00:54.25]1 [00:57.14]2 [01:01.04]3 [01:05.78]4 [01:08.03]5 [01:11.02]6 [01:14.21]7 [01:19.64]8 [01:21.83]9 [01:28.68]a [01:33.34]b [01:36.65]c [01:40.58]d 以下是我目前的思路: 1) 将文本文件复制到字符向量中,在每行

给定文本文件中的以下文本,对于每一个空行,我想取下一行的时间戳,减去0.8,然后把它放在该空行中

[00:00.00]
[00:54.25]1
[00:57.14]2
[01:01.04]3
[01:05.78]4
[01:08.03]5
[01:11.02]6
[01:14.21]7
[01:19.64]8

[01:21.83]9
[01:28.68]a
[01:33.34]b

[01:36.65]c
[01:40.58]d
以下是我目前的思路:
1) 将文本文件复制到字符向量中,在每行末尾追加字符'\n'。
2) 在所有的'\n'中进行循环,直到它连续找到其中的两个。
3) 一旦完成,它会查看接下来的9个字符(不包括最后一个字符']'的时间戳),并将其存储到变量中。
4) 删除不必要的字符“[”和“:”,取前两个数字,乘以60(以使其为秒),然后将其添加到下两个数字中,并将其存储到整数中。
5) 将该整数减去0.8,将秒转换为分钟,将其转换为字符,然后重新添加字符“[”和“:”。
6) 在两个'\n'之间添加时间戳和字符']'。
7) 循环到下一个“\n”

到目前为止,我只将文件推入向量,并尝试寻找两行新行:

[00:00.00]
[00:54.25]1
[00:57.14]2
[01:01.04]3
[01:05.78]4
[01:08.03]5
[01:11.02]6
[01:14.21]7
[01:19.64]8
[01:21.03]
[01:21.83]9
[01:28.68]a
[01:33.34]b
[01:35.85]
[01:36.65]c
[01:40.58]d  
使用名称空间std;
int main(){
ifstream infle(“file.txt”);
矢量线性阵列;
弦线;
字符换行符='\n';
流出流文件(“newfile.txt”);
while(getline(infle,line)){
复制(line.begin()、line.end()、back_inserter(lineArray));
线性排列。推回(换行);
}
对于(std::vector::const_迭代器i=lineArray.begin();i!=lineArray.end();++i)
如果(*i!='\n\n'){

std::cout您的方法还可以,但您可能想得太多了。与其读取所有数据,然后稍后再尝试处理,不如边走边处理

要读取时间戳,不要担心向前看。只需使用
std::regex
分离当前行上的部分,并转换为整数(这允许您决定是否需要插值或偏移)

任何与时间戳模式不匹配的非空行都可能被视为错误,但假设不匹配的模式实际上是空行也可以,因此我的示例将完全忽略任何无效行

using namespace std;

int main() {
    ifstream inFile("file.txt");
    vector<char> lineArray;
    string line;
    char newLine = '\n';
    ofstream outFile("newfile.txt");

    while (getline(inFile, line)) {
        copy(line.begin(), line.end(), back_inserter(lineArray));
        lineArray.push_back(newLine);
    }
    for (std::vector<char>::const_iterator i = lineArray.begin(); i != lineArray.end(); ++i) 
        if (*i != '\n\n') {
            std::cout << *i;
        }

    system("pause");
}
#包括
#包括
#包括
#包括
#包括
int main()
{
常量std::regex时间戳\u regex(“^\\[(\\d+):([0-5]\\d)。(\\d\\d)\\]”;
std::smatch匹配;
std::字符串行;
std::矢量线;
int last_timestamp=0;
bool empty_line=false;
while(std::getline(std::cin,line))
{
//认为非匹配正则表达式为空行,而不是行。
if(std::regex_search(行、匹配、时间戳_regex))
{
int timestamp=std::stoi(匹配[1])*6000
+标准::stoi(匹配[2])*100
+标准::stoi(匹配[3]);
//单空行的偏移或内插时间戳
如果(空_行)
{
空_行=假;
int t=时间戳-80;
如果(toss这里是另一种方法,用于时间戳的解析和格式化,以及时间戳的计算。它需要C++11、C++14或C++17,因为它是基于C++11之前才引入的
。它可以跨Windows、gcc和clang(可能还有其他)移植

#包括“date.h”
#包括
#包括
#包括
int
main()
{
使用名称空间std;
ifstream infle{“file.txt”};
流输出文件{“newfile.txt”};
字符串行号;
istringstream;
使用厘米秒=计时::持续时间;
最后几厘米{0};
constexpr厘米秒ts80{80};
constexpr auto fmt=“[%M:%S]”;
while(填充)
{
//尝试分析时间戳
厘米;
填充>>日期::解析(fmt,ts);
if(infle.fail())
{
//没用,文件结束了?
if(infle.eof())
打破
//好的,假设一个空行并使用它
infle.clear();
填充。忽略(1,“\n”);
//解析下一行并假设它是一个有效的时间戳
填充>>日期::解析(fmt,ts);
断言(!infle.fail());
//创建并格式化插值的时间戳
自动its=ts-最后时刻outFile为什么不在运行时计算时间戳?如果遇到空行,请设置一个标志,然后在读取下一个非空行时,首先按下调整后的空时间戳,重置标志,然后继续。不清楚当您有多个连续的空行时要做什么。如果由空行分隔的时间戳之间的间隔小于800毫秒。是否保证时间戳始终小于99:59.99?我将首先回答后面的问题。保证不会有任何连续的空行。如果由空行分隔的时间戳之间的间隔小于800毫秒,我希望t如果空行有两个时间戳的平均值。是的,时间戳将保证小于99:59.99。至于你的第一个问题,我不太确定是如何做到的。“将该整数减去0.8”你不会对从整数中减去0.8的结果感到满意。最好将整个时间戳转换为整数(m*6000+s*100+分数)和减法80。出于好奇,我对这一切是如何运作的非常感兴趣。如果你有时间,我非常乐意阅读你的推理和你的答案。但是,你给我的答案很多,因此我会将其标记为解决方案。非常感谢。你需要帮助理解解决方案的哪些部分?
#include <iomanip>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

int main()
{
    const std::regex timestamp_regex( "^\\[(\\d+):([0-5]\\d).(\\d\\d)\\]");
    std::smatch match;
    std::string line;
    std::vector<std::string> lines;
    int last_timestamp = 0;
    bool empty_line = false;

    while( std::getline( std::cin, line ) )
    {
        // Consider non-matching regex to be empty line, instead of line.empty()
        if( std::regex_search( line, match, timestamp_regex ) )
        {
            int timestamp = std::stoi( match[1] ) * 6000
                + std::stoi( match[2] ) * 100 
                + std::stoi( match[3] );

            // Offset or interpolate timestamp for single empty line
            if( empty_line )
            {
                empty_line = false;
                int t = timestamp - 80;
                if( t < last_timestamp ) t = (last_timestamp + timestamp) / 2;
                std::ostringstream oss;
                oss << std::setfill('0') << '['
                    << std::setw(2) << (t/6000) << ':'
                    << std::setw(2) << (t/100%60) << '.'
                    << std::setw(2) << (t % 100) << ']';
                lines.emplace_back( oss.str() );
            }
            last_timestamp = timestamp;
            lines.push_back( line );
        }
        else
        {
            empty_line = true;
        }
    }

    // Display all the lines
    for( auto & line : lines )
    {
        std::cout << line << std::endl;
    }
    return 0;
}
#include "date.h"
#include <cassert>
#include <fstream>
#include <string>

int
main()
{
    using namespace std;
    ifstream inFile{"file.txt"};
    ofstream outFile{"newfile.txt"};
    string linenumber;
    istringstream in;
    using centiseconds = chrono::duration<int, centi>;
    centiseconds last_ts{0};
    constexpr centiseconds ts80{80};
    constexpr auto fmt = "[%M:%S]";
    while (inFile)
    {
        // Try to parse a time stamp
        centiseconds ts;
        inFile >> date::parse(fmt, ts);
        if (inFile.fail())
        {
            // Didn't work.  End of file?
            if (inFile.eof())
                break;
            // Ok, assume a blank line and consume it
            inFile.clear();
            inFile.ignore(1, '\n');
            // parse next line and assume it is a valid time stamp
            inFile >> date::parse(fmt, ts);
            assert(!inFile.fail());
            // Create and format the interpolated time stamp
            auto its = ts - last_ts < ts80 ? (ts + last_ts) / 2 : ts - ts80;
            outFile << date::format(fmt, its) << '\n';
        }
        getline(inFile, linenumber);  // parse optional line number
        // Format current time stamp, unchanged.
        outFile << date::format(fmt, ts) << linenumber << '\n';
        last_ts = ts;
    }
}