// Считываем строчку, конец которой определяется кодом перевода строки '\n'. Максимальный размер указываем как второй параметр
cin.getline (buf, gMaxLen, '\n');
fs << buf << endl; //Сбрасываем буфер в поток вывода, связанный с файлом
}
fs.flush(); // Необходимо вызвать для окончательной записи в файл. Ее задача поместить содержимое внутреннего буфера в файл
}
// Эта функция подсчитывает число значимых символов в файле (т.е. за исключением служебных, пробелов etc.)
// а также количество слов и помещает эти занчения в параметры length и nWords
void GetLengthAndWords (fstream& fs, int& length, int& nWords)
{
length = 0; nWords = -1; // Устанавливаем начальные значения (nWords = -1 будет свидетельствовать об ошибке)
char buf[gMaxLen + 1]; // Организуем буфер
fs.clear(); // Сбрасываем указатель файла (обязательное действие см. MSDN Q146445)
fs.seekg (0, ios::beg); // Позиционируем указатель на начало файла
for (; !fs.eof(); nWords++) // Организуем цикл от начала файла и до конца, считаем число слов...
{
fs >> buf;
length += (int)strlen(buf); //...и число символов
}
}
// Эта функция заполняет буфер buffer содержимым файла fs и устанавливает указатели pointers на начала слов
// таким образом буфер представляется одномерным непрерывным массивом слов без каких-либо
// разделяющих символов, символов перевода каретки и пр.
void PopulateBuffer (fstream& fs, char buf[], char* pointers[])
{
fs.clear(); // Сбрасываем указатель файла (обязательное действие см. MSDN Q146445)
fs.seekg(0, ios::beg);
for ( ; !fs.eof(); pointers++)
{
fs >> buf; // Считываем одно слово в буфер
*pointers = buf; // Устанавливаем указатель на начало буфера
buf += strlen (buf); // Сдвигаем начало буфера на длину слова
}
*buf = 0; // Устанавливаем конец буфера
*pointers = 0; // Устанавливаем конец массива указателей
}
void ShowPointersById (char* pointers[], int id) // Вспомогательная функция, выводящая слово по индексу
{
if (pointers[id] && pointers[id+1]) // Длину слова определяем вычитая указатели
cout.write( pointers[id], pointers[id+1] - pointers[id]);// Выводим столько, сколько надо
}
void ShowWords (char* pointers[], int count) // Выводим count слов на экран
{
cout<<"\n\nWords:\n\n";
for (int i=0; i<count; i++)
{
cout<<'\n'<<i+1<<".\t";
ShowPointersById (pointers, i);
}
}
//====== Вывод count слов в порядке определяемом массивом order
void PrintPointersByOrder(char* pointers[], int order[], int count)
{
cout<<"\n\nOrdered Words:\n\n";
for (int i=0; i<count; i++)
{
cout<<'\n'<<i+1<<".\t";
ShowPointersById (pointers, order[i]);
}
}
int StringCompare (char* p[], int i1, int i2)
{
char *p1 = p[i1], *p2 = p[i2];
int n1 = p[i1 + 1] - p1,
n2 = p[i2 + 1] - p2,
i = 0;
for ( ; i<n1 && i<n2 && p1[i] == p2[i]; i++)
;
if (i < n1 && i<n2)
return p1[i] < p2[i] ? -1 : p1[i] > p2[i] ? 1 : 0;
else
return i < n1 ? 1 : i < n2 ? -1 : 0;
}
//========= Сортируем массив order, так, чтобы слова на которые указываю pointers оказались в алфавитном порядке
void SortOrderAlpha (char* pointers[], int order[], int count)
{
for (int i=0; i<count-1; i++) // Организуем цикл до предпоследнего слова
{
int id1 = order[i], // текущий индекс
id2 = order[i+1]; // следующий индекс
if (StringCompare (pointers, id1, id2) > 0) //Сравниваем слова...
{
order[i] = id2; //...и если надо упорядочиваем...
order[i+1] = id1;
i = -1; //...не забывая сбросить счетчик.
}
}
}
void main ()
{
cout<<"Enter a text file name, please: "; // Запрашиваем имя файла
char filename[20]; // Организуем буфер для хранения
cin>>filename; // Считываем имя файла
fstream* fs = new fstream (filename, ios_base::in); // Открываем файловый поток
if (!*fs) // Если неудачно - пытаемся создать новый
{
fs = new fstream (filename, ios_base::out);
if (!*fs)
return;
ReadTextAndSave (*fs); // Вызываем функцию ввода и записи в файл. Ее пропускаем, если открыт существующий файл
fs->close();
fs->open (filename);
}
int length, nWords; // Переменные для хранения числа символов (длины буфера) и числа слов
GetLengthAndWords (*fs, length, nWords); // Определяем длину буфера и число слов
char* buffer = new char[length+1];
char** pointers = new char*[nWords+2]; // Создаем массив указателей на слова
int* order = new int[nWords]; // Создаем массив для упорядочивания слов
PopulateBuffer (*fs, buffer, pointers); // Заполянем буфер и массив указателей
ShowWords (pointers, nWords);
for (int i=0; i<nWords; i++) // Заполняем массив для упорядочивания слов
order[i] = nWords - i - 1;
SortOrderAlpha (pointers, order, nWords); // Сортируем слова
PrintPointersByOrder (pointers, order, nWords); // Выводим слова на экран
fs->close(); //Закрываем файловый поток
delete [] buffer; // Очищаем память
delete [] pointers;
delete [] order;
delete fs;
cout<<"\n\n";
}
Выполните приложение в режиме отладки. Объясните результат. Добейтесь полного понимания того, что происходит. Создайте функцию поиска слов.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.