在C++中将.docx转换为.txt

Oll*_*lie 0 c++ bash

为重复的(我认为)问题道歉,对C++来说是新手,并且已经浏览过但仍然卡住了!

我找到了一个bash脚本,它接受.docx文件并输出纯文本.

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

这比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);
Run Code Online (Sandbox Code Playgroud)

由此没有打印任何内容.

代码使用简单的bash命令,例如'ls'

非常感谢帮助!

Bas*_*tch 5

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

你应该至少使用pclose而不是fclose你应该关心返回的退出代码pclose.

正如评论说Thab不要忘了,\\里面逃生文字字符串(C++编译器的词法,作为在你的字符串字面常量一个反斜杠).您可以使用\\\\或者可以使用C++ 11 原始字符串文字.

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

顺便说一下,也许那个popen失败了,你没有抓住那个.更换

if (fp == NULL) {
   cout << "Error";
}
Run Code Online (Sandbox Code Playgroud)

(缺少std::endl,所以输出没有刷新)

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

最后,我不确定这是在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;
}
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

当然至少取代你的 fclose(fp);

int excod = pclose(fp);
if (excod != 0) 
  clog << "pclose failed " << excod << std::endl;
Run Code Online (Sandbox Code Playgroud)

如果您想了解更多关于退出代码,使用waitpid函数(2)相关的宏上excod(例如WIFEXITED,WEXITSTATUS,WIFSIGNALED,WTERMSIG等...)

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

做一下冲水您的关怀缓冲区(使用的std ::冲洗,性病:: ENDL,fflush(3)等....)开始的过程,当叉(2)(系统(3)popen方法(3)这是fork-ing).