用于阅读 doc、docx、pdf 的 C 程序
C program for reading doc, docx, pdf
我想用 C(只有 c 而不是 c++ 或 java)编写一个程序,它将读取 doc、docx、pdf 并希望在 github 上提供给所有人使用需要那个代码。所以我从 .doc 文件开始探索,如果我用简单的记事本打开 .doc 文件,它会显示所有文本,但只会显示一些额外的内容,您可以轻松 trim。所以我确实写了一个简单的 c 程序来读取 .doc wile 在 'r' 和 'rb' 模式下,但两次它只给我文件中的 5-9 个字符,而且那些也不可读。我不知道为什么会这样。任何评论或讨论都会对我很有帮助。
这里是 link for github Source code。请帮我完成所有三种格式。
将 .doc
文件类型视为 txt
文件,但在您的内容之前、中间和之后有额外的不可打印字符。这些不可打印的字符用于定义特殊格式、元数据和其他信息。
也就是说,所有 .doc
文件都遵循一定的结构。
如果您在十六进制编辑器中打开两个不同的 .doc
文件,您会注意到两个文件的文本内容都从文件开头偏移 0xA00
(2560 字节)处开始文件。这意味着当您最初打开文件时,您可以忽略文件的前 2560 个字节(看看 fseek()
函数)。
从现在开始,您可以阅读文件的内容,直到到达 '[=16=]'
。
我还没有看到 .pdf
或 .docx
文件的实现,但是您可以使用十六进制编辑器打开这两个文件并弄清楚您可以使用哪种模式来隔离文件的重要内容。
希望对您有所帮助。
EDIT :您总能找到有关您要操作的不同文件格式的文档。以下是 PDF 文件类型的规格:
http://www.adobe.com/devnet/pdf/pdf_reference.html
http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf
不要指望这个想法会有所作为。 .doc 是一种巨大的二进制文件格式,解析起来非常复杂。话虽如此,Cubia 提到了文档文本部分开始的偏移量。我不熟悉格式的细节,但如果原始文本包含在一个位置,请使用 fseek
获取它并在到达末尾时停止。其他格式不会出现这种情况,因为它们非常不同。
.docx 和 .pdf 应该更容易解析,因为它们是更现代的格式。如果你想从 docx 中读取任何内容,你需要从一个包含大量 xml 的 zip 文件中读取,然后使用解析器找出你想要的文本。
.pdf 应该是三者中最简单的一个,因为您也许可以在那里找到几乎可以做您想要的事情的库。
至于为什么您的程序会得到奇怪的输出,请记住 .doc 是一种二进制格式,从您的角度来看,绝大多数数据都是垃圾。将其转储到终端将产生可读文本,但也会产生一堆控制字符,这些字符应该会影响您的终端。
最后一点 - 不要尝试直接使用 fread
读取 docx 文件 - 它们经过压缩,因此您可能无法恢复原样的文本。看看 libarchive。另外 - 期望必须阅读文档规范。 docx 似乎是微软对 openoffice 格式的扩展。参见this和一些PDF规范文档(有多个版本)。
为了回答您的具体问题,您的小应用程序停止读取的原因是因为它错误地认为您的文件中有一个 EOF
字符。
看看你的代码:
char ch;
int nol=0, not=0, nob=0, noc=0;
FILE *fp;
fp = fopen("file.doc","rb");
while(1)
{
ch = fgetc(fp);
if(ch==EOF)
{
break;
}
你将fgetc(fp)
的结果存储在一个char类型的变量中,它是一个单字节变量。然而,fgetc 的结果是非常有目的的“int
”,而不是“char
”。
fgetc
始终 returns 在 0 到 255 范围内的正结果,除非当您到达文件末尾时 returns EOF
,通常实现为 -1 值。
如果您读取一个值为 255 的字节并将其存储在一个 int 中,则一切正常,它被存储为值 255 并且您的循环可以继续。如果将结果存储在 char 中,它将被解释为等于 EOF。你的循环停止了。
我想用 C(只有 c 而不是 c++ 或 java)编写一个程序,它将读取 doc、docx、pdf 并希望在 github 上提供给所有人使用需要那个代码。所以我从 .doc 文件开始探索,如果我用简单的记事本打开 .doc 文件,它会显示所有文本,但只会显示一些额外的内容,您可以轻松 trim。所以我确实写了一个简单的 c 程序来读取 .doc wile 在 'r' 和 'rb' 模式下,但两次它只给我文件中的 5-9 个字符,而且那些也不可读。我不知道为什么会这样。任何评论或讨论都会对我很有帮助。
这里是 link for github Source code。请帮我完成所有三种格式。
将 .doc
文件类型视为 txt
文件,但在您的内容之前、中间和之后有额外的不可打印字符。这些不可打印的字符用于定义特殊格式、元数据和其他信息。
也就是说,所有 .doc
文件都遵循一定的结构。
如果您在十六进制编辑器中打开两个不同的 .doc
文件,您会注意到两个文件的文本内容都从文件开头偏移 0xA00
(2560 字节)处开始文件。这意味着当您最初打开文件时,您可以忽略文件的前 2560 个字节(看看 fseek()
函数)。
从现在开始,您可以阅读文件的内容,直到到达 '[=16=]'
。
我还没有看到 .pdf
或 .docx
文件的实现,但是您可以使用十六进制编辑器打开这两个文件并弄清楚您可以使用哪种模式来隔离文件的重要内容。
希望对您有所帮助。
EDIT :您总能找到有关您要操作的不同文件格式的文档。以下是 PDF 文件类型的规格:
http://www.adobe.com/devnet/pdf/pdf_reference.html http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf
不要指望这个想法会有所作为。 .doc 是一种巨大的二进制文件格式,解析起来非常复杂。话虽如此,Cubia 提到了文档文本部分开始的偏移量。我不熟悉格式的细节,但如果原始文本包含在一个位置,请使用 fseek
获取它并在到达末尾时停止。其他格式不会出现这种情况,因为它们非常不同。
.docx 和 .pdf 应该更容易解析,因为它们是更现代的格式。如果你想从 docx 中读取任何内容,你需要从一个包含大量 xml 的 zip 文件中读取,然后使用解析器找出你想要的文本。
.pdf 应该是三者中最简单的一个,因为您也许可以在那里找到几乎可以做您想要的事情的库。
至于为什么您的程序会得到奇怪的输出,请记住 .doc 是一种二进制格式,从您的角度来看,绝大多数数据都是垃圾。将其转储到终端将产生可读文本,但也会产生一堆控制字符,这些字符应该会影响您的终端。
最后一点 - 不要尝试直接使用 fread
读取 docx 文件 - 它们经过压缩,因此您可能无法恢复原样的文本。看看 libarchive。另外 - 期望必须阅读文档规范。 docx 似乎是微软对 openoffice 格式的扩展。参见this和一些PDF规范文档(有多个版本)。
为了回答您的具体问题,您的小应用程序停止读取的原因是因为它错误地认为您的文件中有一个 EOF
字符。
看看你的代码:
char ch;
int nol=0, not=0, nob=0, noc=0;
FILE *fp;
fp = fopen("file.doc","rb");
while(1)
{
ch = fgetc(fp);
if(ch==EOF)
{
break;
}
你将fgetc(fp)
的结果存储在一个char类型的变量中,它是一个单字节变量。然而,fgetc 的结果是非常有目的的“int
”,而不是“char
”。
fgetc
始终 returns 在 0 到 255 范围内的正结果,除非当您到达文件末尾时 returns EOF
,通常实现为 -1 值。
如果您读取一个值为 255 的字节并将其存储在一个 int 中,则一切正常,它被存储为值 255 并且您的循环可以继续。如果将结果存储在 char 中,它将被解释为等于 EOF。你的循环停止了。