对于C ++中新出现的重复(我认为)的问题,我们深表歉意。

我发现一个bash脚本需要一个.docx文件并输出纯文本。

unzip -p filename.docx word/document.xml | sed -e 's/<[^>]\{1,\}>//g; s/[^[:print:]]\{1,\}//g'


这比bash效果更好。

然后在我的代码中使用它:

FILE *fp = popen("unzip -p filename.docx word/document.xml | sed -e 's/<[^>]\\{1,\\}>//g; s/[^[:print:]]\\{1,\\}//g'", "r");
char buf[1024];

if (fp == NULL) {
    cout << "Error";
}

while (fgets(buf, 1024, fp)) {
    /* do something with buf */
    cout << buf;
}

fclose(fp);


因此,不会打印任何内容。

该代码可与简单的bash命令(例如“ ls”)一起使用

并且帮助将不胜感激!

最佳答案

(我假设您的程序应在某些Linux系统或至少某些POSIX系统上运行)

您至少应使用pclose而不是fclose,并且应注意pclose返回的退出代码。

正如Thab所评论的那样,请不要忘记\\literal strings内部的转义符(C ++编译器是lexing,它是字符串文字常量中的单个反斜杠)。您可以使用\\\\或C ++ 11 raw string literals

(您当然应该检查例如调试器,popen正在处理的字符串是什么)

顺便说一句,也许popen失败了,但您没有意识到这一点。更换

if (fp == NULL) {
   cout << "Error";
}


(缺少std::endl,因此未刷新输出)



if (fp == nullptr) {
  close << "popen failed:" << strerror(errno) << std::endl;
  exit(EXIT_FAILURE);
}


最后,我不确定这是否是在Linux上以批处理模式将.docx转换为.txt的好方法。我会考虑分派Libreoffice或Openoffice流程来完成这项工作(也许libreoffice --headless --cat和更多选项)。我不知道所有详细信息,您需要RTFM

顺便说一句,您可能应该编写一些小的Shell脚本进行转换,在终端中对其进行检查和测试,然后使用popen调用该Shell脚本(因此避免使用反斜杠的命令行)。

最后,您的C ++代码太像C。我建议使用getline(3)以便替换

while (fgets(buf, 1024, fp)) {
  /* do something with buf */
  cout << buf;
}




char* linbuf = nullptr;
size_t linsiz = 0;
do {
  ssize_t linlen = getline(&linbuf, &linsiz, fp);
  if (linlen<=0) break;
  cout << std::string(linbuf, linlen) << std::endl;
} while (!feof(fp));
free (linbuf), linbuf=nullptr;


当然,至少应将fclose(fp);替换为

int excod = pclose(fp);
if (excod != 0)
  clog << "pclose failed " << excod << std::endl;


如果您想进一步了解退出代码,请在excod上使用与waitpid(2)相关的宏(例如WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIG等)。

不要忘记编译所有警告和调试信息(g++ -Wall -Wextra -g)并使用调试器(gdb),strace(1)valgrind

在开始使用fork-的buffers(或std::flushstd::endl)启动进程时,请注意冲洗fflush(3)(使用fork(2)system(3)popen(3)等)。 ing)。

关于c++ - 在C++中将.docx转换为.txt,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33101845/

10-11 03:38
查看更多