Страница Ивана Рощина > Статьи >

© Иван Рощин, Москва

ZXNet: 500:95/462.53
E-mail: bestview@mtu-net.ru
WWW: http://www.ivr.da.ru

Простейший конвертор DOC –> TXT

Радиомир. Ваш компьютер» 10/2003)

Так случилось, что мне надо было посмотреть несколько текстов в формате Microsoft Word (файлы с расширением DOC). Устанавливать этот редактор я не собирался, да его у меня и не было. Поэтому я попытался найти в Интернете программу для просмотра DOC-файлов или преобразования их в обычный текст. Увы, безуспешно. Или найденная программа требовала наличия Microsoft Word, или была написана для UNIX, или не желала запускаться… Тогда я решил попробовать сам написать простейший конвертор DOC –> TXT.

Какой-либо информации о формате DOC-файлов у меня не было, а было несколько таких файлов (причём текст, содержащийся в одном из них, также имелся у меня в простом текстовом файле). В результате изучения содержимого этих файлов удалось обнаружить следующие закономерности:

Конечно, вышеизложенная информация очень неполна, да, может быть, и неточна (так как получена в результате анализа лишь нескольких DOC-файлов), но её оказалось достаточно, чтобы написать небольшую программу для преобразования DOC –> TXT, с помощью которой я успешно сконвертировал эти DOC-файлы. Судя по находившимся в этих файлах текстовым строкам, они были созданы с помощью Microsoft Word версий 8.0 и 9.0.

Я, конечно, не надеюсь, что моя программа будет правильно конвертировать любые DOC-файлы. Но если она помогла мне, то, может быть, поможет и вам.

При запуске программы надо указать в командной строке следующие параметры: имя исходного файла, имя получаемого файла и необязательный параметр «/a». Исходный и получаемый файлы считаются находящимися в текущем каталоге.

От параметра «/a» зависит, как конвертор будет определять конец текста в DOC-файле. Если этот параметр не указан, конвертор будет считать, что текст закончился и начались служебные данные, когда очередные два считанных байта окажутся нулями. Но если два нулевых байта попадутся внутри текста (а исключать этого нельзя, ведь мне не известна полная информация о формате DOC-файлов), то конец текста будет определён раньше времени. А если параметр «/a» указан, программа закончит конвертацию, только когда закончится исходный файл. Но тогда в конце полученного файла будет «мусор» из служебных данных.

В процессе конвертации программа после обработки каждых 32768 символов текста печатает на экране «*», показывая, что она не зависла.

Ниже приведён текст программы на языке Си.

/* ================================================= */
/* DOC2TXT - извлечение текста из документов MS Word */
/* ================================================= */
/* Compiler: Turbo C 2.0                             */
/* ================================================= */

#include <stdio.h>

void main (int argc, char *argv[])
{
 FILE *f_src, *f_dst;
 int c1,c2;
 char *rus_big="АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
 char *rus_small="абвгдежзийклмнопрстуфхцчшщъыьэюя";

 printf ("\nDOC to TXT file convertor  (c) Ivan Roshin, Moscow, 2003.\n");
 if (argc<3)
 {
  printf ("Syntax: doc2txt.exe source-file destiny-file [/a]\n\n"); exit();
 }

 f_src=fopen(argv[1],"rb");
 if (f_src==NULL) {printf ("Error: can't open source file!\n\n"); exit();}

 f_dst=fopen(argv[2],"wb");
 if (f_dst==NULL) {printf ("Error: can't open destiny file!\n\n"); exit();}

 fseek(f_src,0x600,SEEK_SET);
 do
 {
  c1=fgetc(f_src);
  c2=fgetc(f_src);
  if (c2==0)
  {
   if (c1==13) fputs ("\r\n    ",f_dst); /* Перевод строки и абзацный отступ. */
   if ((c1>=0x20)&&(c1<=0x7F)) fputc (c1,f_dst);
  }
  if (c2==4)
  {
   if ((c1>=0x10)&&(c1<=0x2F)) fputc (rus_big[c1-0x10],f_dst);
   if ((c1>=0x30)&&(c1<=0x4F)) fputc (rus_small[c1-0x30],f_dst);
  }
  if (c2==0x20)
  {
   if (c1==0x14) fputc('-',f_dst); /* Тире. */
   if (c1==0x1c) fputc('"',f_dst); /* Открывающие кавычки. */
   if (c1==0x1d) fputc('"',f_dst); /* Закрывающие кавычки. */
  }
  /* Через каждые 32768 выведенных символов печатаем на экране "*". */
  {
   static unsigned int counter=0;
   counter++;
   if ((counter&0x7fff)==0) printf ("*");
  }

 /* Главный цикл выполняется, пока не встретится 0,0 или не кончится файл
    (если при запуске был указан третий параметр "/a", цикл будет выполняться,
    пока не кончится файл, даже если встретится 0,0; в программе для простоты
    проверяется только количество параметров). */

 } while ((c1!=EOF)&&(((c1|c2)!=0)||(argc==4)));
 fcloseall();
}
Скачать исполняемый файл программы (для DOS) (6 КБ ZIP)
Скачать листинг программы в текстовом виде (1 КБ ZIP)

От редакции: в данном случае под DOC-файлами подразумеваются файлы именно WinWord (v.8—9), которые используют для кодировки символов Unicode. Word 6 и 7 по умолчанию сохраняют текст в win-1251 и используют для кодировки одного символа один байт. Поэтому данный конвертор с ними не работает.

От автора: при использовании конвертора выяснилось ещё одно обстоятельство. Если в DOC-файле имеются достаточно длинные фрагменты текста с использованием символов только из нижней половины кодовой таблицы (например, текст на английском языке или листинг программы), то эти фрагменты могут находиться в «обычном» виде (один байт — один символ), и в этом случае конвертор не сможет их правильно обработать (они будут пропущены). К тому же в файле после таких фрагментов может находиться последовательность нулей, поэтому конвертор надо запускать с параметром «/a», чтобы он не принял эти нули за конец текста.

Замечу, что наличие таких фрагментов в DOC-файле легко обнаружить, просмотрев его содержимое: участки текста в «обычном» виде сразу будут заметны. А если текст только на русском языке, то и вообще беспокоиться не о чем.

Страница Ивана Рощина > Статьи >