【问题标题】:output redirection in the function system() seems not to work函数 system() 中的输出重定向似乎不起作用
【发布时间】:2016-03-17 22:45:22
【问题描述】:

我一直在为这个问题摸不着头脑,也无法通过网上冲浪找到任何答案。

问题是我在我的程序中调用system("csvtojson someFile.csv 1> someOtherFile.json") 来生成一个JSON 文件。在这一行之后,我想打开、读取和处理 JSON 文件。虽然,我可以看到文件已创建,但fopen() 返回NULL。 我读到system() 是同步的,所以我认为我的程序的其余部分在system 调用完成之前不会执行,因此将创建文件。

我怀疑问题与使用“1>”重定向输出流有关;不过不确定。

任何帮助或提示将不胜感激。

谢谢! :)

附:我不想使用库将 csv 转换为 JSON,我无法在程序外部执行转换,因为有大量非常大的 csv 文件,我唯一的方法是将每个文件转换为内部的 JSON 文件程序,运行我的算法,然后移动到下一个 csv 文件(将其转换为 JSON 并将其保存在同一个 JSON 文件中)。所以总的来说我只有一个 JSON 文件,就像我的 csv 文件的缓冲区。话虽如此,如果有人有更好的设计方法可以快速实施,那也很棒。

更新:显示问题的实际代码,复制自 OP 的答案:

int main(){
system("csvtojson Test_Trace.csv 1> ~/Traces/Test_Trace.json");

FILE* traceFile = fopen("~/Traces/Test_Trace.json", "r");
if(traceFile == NULL)
  perror("Error in Openning the trace file");
else
  cout << "Successfull openning of the trace file!" << endl;

 return 0;
}

【问题讨论】:

  • 你说你可以看到文件被创建(如何?),但是fopen()返回NULL。是否设置errno?在调用fopen() 之前将errno 设置为0,然后如果fopen() 失败,则在调用后查看其值(或使用perrorstrerror 以获得可读的错误消息)。
  • @KeithThompson 你不需要清除errno
  • @EJP:也许吧,但不会有什么坏处。 C 标准不要求 fopen 在失败时设置 errno,但 POSIX 需要。
  • @KeithThompson,该文件已创建,因为我可以在目录中看到它,打开它,它在那里工作正常。我用perror,消息是:No such file or directory
  • 所以你的程序完成后文件就存在了,对吧?您能否更新问题以显示更多代码,至少包括从system() 调用到fopen() 调用的所有内容?另外,尝试将1&gt; 更改为&gt;(应该做同样的事情,但更惯用);如果这没有帮助,您可以从您的问题中删除该段落。

标签: c++ io


【解决方案1】:

谢谢你们的回答。我的问题必须更详细,因为问题似乎出在我的问题中并不清楚的地方。

我发现了问题所在,并想在这里分享(不是一个非常有趣的发现,但值得一提)。

我写了一个简单的程序来查找问题:

int main(){
system("csvtojson Test_Trace.csv 1> ~/Traces/Test_Trace.json");

FILE* traceFile = fopen("~/Traces/Test_Trace.json", "r");
if(traceFile == NULL)
  perror("Error in Openning the trace file");
else
  cout << "Successfull openning of the trace file!" << endl;

 return 0;
}

如果您运行此程序,您将收到错误消息No such file or directory,但如果您在system(...)fopen(...) 调用中将地址字符串替换为绝对位置,即/home/USER_ID/Traces/Test_Trace.json,您的代码将工作正常。有趣的是,我自己怀疑这可能是问题所在,我只更改了system(...) 的那个,但它仍然无法正常工作(尽管文件是在传递给fopen(...) 的位置创建的)。

编辑:感谢@Peter 的评论,这个问题是因为 system() 调用处理了~,但 fopen() 不需要并且需要绝对路径。所以真的没有必要给这两个函数都指定绝对路径。

无论如何,

再次感谢。 :)

【讨论】:

  • ~ 扩展到您的主目录是由您选择的 shell 或命令解释器完成的,system() 通常会启动它来托管并执行提供的命令。 fopen() 不做这种扩展——它依赖于调用代码来做。这通常通过编写获取环境变量 HOME 的值的代码(例如使用 getenv())并在调用 fopen() 之前将其添加到字符串中以代替 ~ 字符来完成。像 1&gt; 这样的重定向也是你的命令 shell 的一个功能。
  • 这就是为什么我们应该首先显示所有相关的代码部分,将您的电话发布到fopen() 会在十分钟内得到来自社区的快速答复。
  • fopen() 不需要绝对路径;相对路径工作得很好。它只是不执行 shell 所做的扩展,例如 ~$VAR 等。顺便说一句,包括您在问题中的实际代码会为我们节省大量时间。
【解决方案2】:

这可能是因为系统命令在您的程序继续执行下一条指令时尚未完成执行,它试图从尚未创建的文件中读取。

虽然这不是最好的方法,但稍作停顿可能会有所作为,或者至少让您知道这是否是问题所在。

【讨论】:

    猜你喜欢
    • 2012-09-13
    • 2011-09-22
    • 2021-12-13
    • 2013-06-19
    • 2023-04-09
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多