2013-02-25 57 views
0

我有一个使用Direct-show抓取视频的程序。我的问题是我想要保存的视频有时间作为名称。以下是我所做的:获取时间作为文件名

CoInitialize(NULL); 
CComPtr<IGraphBuilder> graph; 
graph.CoCreateInstance(CLSID_FilterGraph); 
time_t rawtime; 
struct tm * timeinfo; 
time (&rawtime); 
timeinfo = localtime (&rawtime); 
wchar_t pathstuff[50]; 
swprintf(pathstuff, L"D:\\BMDvideos\\%hs.avi", asctime(timeinfo)); 
LPCOLESTR x = pathstuff; 
HRESULT hr = BuilGraph(graph,x); 
.......... 

这不起作用,任何想法我怎么能做到这一点?

+0

您是否检查过,如果您的'timeinfo *'包含有效数据? – 2013-02-25 09:25:44

+2

@ bash.d更可能的问题是他在Windows下。 'asctime'在其格式中使用冒号,Windows不允许在文件名中使用冒号(除了特殊用途,如初始设备说明符或辅助流)。 – 2013-02-25 09:30:18

+0

@JamesKanze很高兴知道! – 2013-02-25 09:31:02

回答

3

格式化时间的功能是strftime,所以你可以做 类似:

char filename[1000]; 
size_t l = strftime(filename, 
        sizeof(filename), 
        "D:/BMDvideos/%Y-%m-%dT%Hh%Mm%S.avi", 
        timeinfo); 
assert(l != 0); 

几点意见:

  • 你做要宽字符的文件名。他们不是 标准,并没有得到广泛的支持。 (对于 Unicode文件名的通用标准是UTF-8,它确实工作无处不在。在 其实,你不希望你的外部程序 随时随地宽字符。)

  • 不能使用任何标准的格式化功能,如 asctime,因为它们几乎肯定会在Windows下使用冒号(':') 时间格式,并且冒号在文件名 中是非法字符。您必须自己指定确切的格式, 使用strftime

  • 有可能还有很多其他字符,你应该避免 以及。我倾向于将我的文件名限制为字母数字, 下划线,连字符和圆点,并且我不确定连字符的可移植性或带有多个点的名称。如果 的名称不适合人类消费,那么我只是使用 "%Y%m%d%H%M%S",没有分隔符。

  • 最后,是非常有用的使用日期的ISO排序(年,月,日 ),因为这意味着词典编纂整理 对应于日期排序。

编辑:

既然你说你必须使用wchar_t文件名(这是 一个非常糟糕的政策):你仍然可以使用上面生成 文件名,然后将其转换为std::wstring通过简单地使用 std::wstring(filename, filename + strlen(filename))

+0

感谢您的回答,但它的工作,但我仍然需要宽字符文件名 – Engine 2013-02-25 10:02:59

+1

@Engine为什么? Windows将同时接受本地磁盘,但如果您想要备份(可能通过NFS),或执行其他任何可能导致文件被非Windows系统看到的情况,您将遇到麻烦。 (这两种方式都有效:我在Linux下生成包含冒号的文件名时遇到了问题,当文件系统安装在Windows机器上时,导致问题没有结束。)但是,如果您必须:只需将生成的字符串复制到'std :: wstring'(使用两个迭代器构造函数)。如果文件名是纯ASCII,这将起作用。 – 2013-02-25 10:06:59

+0

@Engine无论如何,我已经编辑了答案来解释这一点。 – 2013-02-25 10:11:59

1

asctime增加'\ N'在返回字符串的末尾字符,其不是有效的文件名

呼叫的ctime(t)是与asctime(本地时间(T))。它 日历时间t转换成 形式

  "Wed Jun 30 21:49:08 1993\n" 

尝试使用的strftime的空终止字符串isntead

char name[100] 
strftime(name, 100, "%F_%R", timeinfo); 
+1

不要使用'“%R”'。这将在Windows下的文件名中插入冒号,这不是合法的字符。 – 2013-02-25 10:08:12

1

wchar_t *LPCOLESTR不兼容的类型,在运行时。你读过this BSTR manual吗?它会告诉你如何正确分配你的BSTR。