我有一个粒子系统程序,该程序会在每次迭代中生成带有粒子坐标的.dat
文件。最终目标是通过具有不同参数的脚本多次运行该程序。因此,我试图以一种方式来设置程序,以便每次运行时所有相关数据都将存储在一个文件夹中。
我要做的是使用PNGs
从.dat
文件生成Gnuplot
,调用ffmpeg
从PNGs
创建视频,使用WinRAR
压缩.dat
文件,最后清理,通过删除所有中间文件。当我在工作目录中执行此操作时,此方法有效。
现在,我尝试创建一个新目录并在其中执行相同的操作。我的代码:
// Load the proper library to use chdir() function
#ifdef _WIN32
#include <direct.h>
#elif defined __linux__ || defined __APPLE__&&__MACH__
#include <unistd.h>
#endif
// Make output directory and change working directory to new directory
ostringstream dirCommand;
dirCommand << "mkdir " << folderName_str;
system(dirCommand.str().c_str());
const char* test = folderName_str.c_str();
#ifdef _WIN32
if(_chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#elif defined __linux__ || defined __APPLE__&&__MACH__
if(chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#endif
else
printf("Created output directory...\n");
对于这一部分,我已经知道会有异议。我对SO进行了广泛研究,许多人赞成Windows使用
SetCurrentDirectory()
,或者他们对使用system()
持怀疑态度。在我的辩护中,我是一名新手程序员,我的知识真的很有限。现在,当我尝试使用
FFMpeg
制作视频,然后rar / tar我的文件时:// Make video
std::cout << "Generating Video..." << endl;
ostringstream command;
command << "ffmpeg -f image2 -r 1/0.1 -i output_%01d.png -vcodec mpeg4 " << videoName_str << ".avi -loglevel quiet";
std::system(command.str().c_str());
// Clean Up!
std::cout << "Cleaning up!" << endl;
ostringstream command2;
#ifdef _WIN32
command2 << "rar -inul a " << videoName_str << ".rar *.dat settings.gp loadfile.gp";
#elif defined __linux__ || defined __APPLE__&&__MACH__
command2 << "tar cf " << videoName_str << ".tar *.dat settings.gp loadfile.gp";
#endif
std::system(command2.str().c_str());
我在Win / Linux中得到了截然不同的行为。
Win 7 x64,Visual Studio 2010/12
在Windows中,将创建文件夹。
.dat
文件生成正确,并且gnuplot
也会绘制PNGs
。调用ffmpeg
时,没有任何反应。没有来自FFMpeg
或其他任何错误消息。 WinRAR
也是如此。也许,对于最后一件事,我可以使用免费的7z
命令行实用程序!Linux Mint 14 x64,Qt 4.8.1
奇怪的是,其行为与Windows相反。更改目录后,只会生成第一个
.dat
文件。好像我为生成文件而对fprintf()
进行的每个后续调用都无效,或者丢失了某个地方。 Gnuplot
起作用,ffmpeg
和tar
也一样!我真的很困惑。任何帮助将非常感激。
最佳答案
以下几点可能会有所帮助:
确保检查每个系统调用的结果,包括system()和fprintf()。
自从我上次接触Windows已经有一段时间了。我记得,取决于二进制文件的链接方式,它们不一定会输出到同一控制台。因此,ffmpeg / winrar可能会丢弃错误消息,或者只是分配一个新的,短暂的控制台进行打印。
我会使用mkdir / _mkdir而不是调用system()。
使用popen()/ _ popen()可以更好地控制错误输出。
考虑使用Shell脚本或bat文件。
关于c++ - system()调用使用不当?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16780811/