2015-10-13 139 views
0

对于C++中新增的(我认为)重复的问题抱有歉意,并且已经观察过但仍然卡住!在C++中将.docx转换为.txt

我发现了一个带有.docx文件并输出纯文本的bash脚本。

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”的

和帮助,将不胜感激!

+1

难道你不需要逃避每个反斜杠吗? – thab

+0

那么有四个反斜杠?像这样:'unzip -p filename.docx word/document.xml | sed -e's/<[^>] \\\\ {1,\\\\}> // g; s/[^ [:print:]] \\\\ {1,\\\\} // g'“,”r“' – Ollie

+1

试一下吗?它在bash中只有2个,那么你需要4是的 – thab

回答

5

(我假设你的程序应一些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)所以用

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; 

当然更换

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

更换至少你的fclose(fp);

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

如果您想了解更多关于退出代码,使用waitpid(2)excod(例如:WIFEXITED,WEXITSTATUSWIFSIGNALEDWTERMSIG等....)

不要忘了所有警告&调试信息(g++ -Wall -Wextra -g编译),并使用调试器(gdbstrace(1),& valgrind

做一下冲水照顾你buffers(使用std::flush,std::endl,fflush(3)等)。

+0

感谢您提供的所有建议,它非常有帮助! 当我现在运行该程序时,excod为0,但是没有打印任何结果循环。 我会检查您添加的所有链接,并希望能够开展工作! 我在OSX v10.11上运行它 – Ollie

+0

自从我上次发表评论以来,我设法使用您的建议来运行它。再次感谢您的帮助! – Ollie