Программа для форматирования текста!

Тема в разделе "C/C++/C#", создана пользователем Andersen1313, 18 окт 2010.

  1. Andersen1313

    Andersen1313 New Member

    Регистрация:
    18 окт 2010
    Сообщения:
    4
    Симпатии:
    0
    Помогите написать программу или хотя бы нарисуйте алгоритм работы программы:

    Имеется текстовый файл. Написать программу, которая перефор¬матирует каждую его страницу в три колонки. Все колонки должны быть выровнены по ширине. Параметры форматирования:
    - ширина колонок выходного файла;
    - расстояние между колонками.

    Заранее спасибо!
     
  2. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Слова разрывать нельзя?
    И выравнивание по ширине пробелами между слов?
     
  3. Andersen1313

    Andersen1313 New Member

    Регистрация:
    18 окт 2010
    Сообщения:
    4
    Симпатии:
    0
    Да выровнять пробелами, не разрывая слов
     
  4. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    По заданию сначало показалось, что алгоритм тривиальный, по-ходу выполнения он все растягивался и растягивался ;-))
    Хорошая задачка... Мне лично понравилась....

    Код (C++):
    #include <iostream>
    #include <ctype.h>

    using namespace std;
    /*АЛГОРИТМ ПОКАЖУ НА СТРОКЕ (ВПРИНЦИПИ) с файлом все тоже самое только считывать файл лучше постранично, размер страницы уже сами решайте какой*/

    char *S = "Подразделения компании также производят семейство игровых консолей XBOX, портативные медиаплееры Zune, а также аксессуары для персональных компьютеров (клавиатуры, мыши и т. д.). Продукция Microsoft продаётся более чем в 80 странах мира, программы переведены более чем на 45 языков. Штаб-квартира компании находится в городе Редмонд. Штат сотрудников корпорации составляет порядка 90 тысяч человек. На территории России с ноября 1992 года действует представительство Microsoft (с июля 2004 года — ООО «Майкрософт Рус»). Microsoft находится под надзором суда в результате мирового соглашения 2002 года.... (c) Вырезка с какого то сайта";
    char *Sl[10000]; //Массив слов /*для файла лучше использовать динамику к примеру char *Sl = new char[кол-во байт файла]/или страницы
    char *SlW[10000]; //Массив строк колонки (идущие подряд слова которые в мещаются в длину колонки /*для файла тоже лучшеь динамика к примеру char *Sl = new char[кол-во байт файла]/или страницы
    int sl=0; //Счетчик слов
    int slw=0; //Счетчик колонок

    //Главная функция программы
    void main(void)
    {
    setlocale(LC_ALL,"Russian"); //Локаль

    int width = 20; //Ширина колонки
    int Column =2; //Кол-во колонок

    char buffer[128]; //Буферная переменная для слова
    memset(buffer,0,128); //Обнулим память buffer
    char *ptr=buffer; //Указатель на буфер

    //Получение всех слов
    for (int i=0; i<=strlen(S);i++) //Обойдем всю строку
    {
    if (isspace((unsigned char)S[i])) //Если символ - разделитель пространства
    {
    cout<<"Слово "<<sl<<"> "<<buffer<<endl; //Для отладки : Выведим слово на экран
    Sl[sl] = new char[strlen(buffer)]; //Динамически выделим память для слова
    strncpy(Sl[sl],buffer,strlen(buffer)+1); //Запишим слово и завершающий (0-символ)
    memset(buffer,0,128); //Обнулим буфер будем писать заново
    ptr = buffer; //Указатель на нулевую память тоже заново поставим
    sl++; //Увеличим счетчик слов
    continue; //Продолжим цикл
    }
    *ptr++ = S[i]; //Запишим в буфер символ и сдвиним указатель на байт
    }
    if (strlen(buffer) !=0)
    {
    Sl[sl] = new char[strlen(buffer)]; //Динамически выделим память для слова
    strncpy(Sl[sl],buffer,strlen(buffer)+1); //Запишим слово и завершающий (0-символ)
    cout<<"Слово "<<sl<<"> "<<buffer<<endl; //Для отладки : Выведим слово на экран
    }

    SlW[slw] = new char[width+1]; //Выделим память под строку размером ширина-колонки +1
    memset(SlW[slw],0,width+1); //Обнулим выделеную память
    //Получение строк заданной ширины (из слов)
    for (int i=0, size = 0; i<=sl; i++) //Обойдем весь массив слов
    {
    if (strlen(SlW[slw]) + strlen(Sl[i]) <= width) //Если сумма текущей строки + длина сл. слова <= ширины колонки, значит мы можем включить еще слово
    {
    strcat(SlW[slw],Sl[i]); //Объеденим текущую строку и слово
    strcat(SlW[slw]," "); //Поставим пробел в конец
    }
    else //Если же слово уже не вместить
    {      
    SlW[slw][strlen(SlW[slw])-1] = 0;//Уберем последний пробел
    int dt = width - strlen(SlW[slw]); //Найдем отклонение сколько пробелов для выравнивания нам нужно добавить

    char *temp = new char[width+1]; //Заведем динамическую строку (можно кстати buffer использовать, но так нагляднее)
    memset(temp,0,width+1); //Обнулим ее память

    char *ptemp = SlW[slw]; //Заведем указатель на строку-колонку
    char *ptemp2 = NULL; //И еще один указатель пригодится позже

    //Щас бы нам не плохо бы найти величину на сколько пунктов нам требуется увеличить пробелы(разрыв между слов)
    //что бы за один обход строки-колонки заполнить этим и займемся
    int cnt = 0; //Заведем счетчик
    while (strstr(ptemp," ")) //Пока в строке на которую указывает указатель ptemp есть пробел, то
    {
    ptemp = strstr(ptemp," ")+1; //Сместим указатель на символ идущий за первым пробелом
    cnt++; //увеличим счетчик
    }
    int NomSpace; //кол-во пунктов
    if (cnt !=0) //Сдесь сделаем проверку, если в строке-колонке у нас одно слово, то cnt Будет равен 0, а делить на нуль нелья
    {
    NomSpace = (int)(dt/cnt)+1; //Тут найдем как раз требуемое кол-во пунктов +1 - т.к. округление идет в мин (отбрасывание дробной части)
    }
    else //Если же слово всего одно
    {
    NomSpace = 0; //То сразу докидаем его пробелами
    for (int m=0; m<dt;m++)
    {
    strcat(SlW[slw]," ");
    }              
    dt = 0;
    }
    //
    ptemp = SlW[slw];//Сделаем что бы указатель указывал на строку-колонку
    ptemp2 = temp; //А второй указатель на динамическую строку temp
    while (*ptemp) //Пока указатель указывает на не нулевой символ строки
    {
    if (*ptemp == ' ') // Если указатель на строку-колонку указывает на пробел
    {
    for (int j=0; j < NomSpace && dt>0; j++) //Поставим наши разрывы, но с проверкой на отклонение
    {
    *ptemp2 = ' '; //Запишим в буфер
    ptemp2++; //Сместим указатель который указывает на буфер //Тут бы список задачу упростил, но ладно, уже выбран массив
    dt--; //Уменьшим отклонение на 1 пунке
    }
    }
    *ptemp2 = *ptemp; //Пишим посимвольно в Буфер из строки-колонки
    ptemp++; //Сместим указатель
    ptemp2++; // И этот тоже
    }
    strcpy(SlW[slw],temp); //Скопируем из темпа в строку-колонку (тоесть заменим на уже выравненую строку-колонку)
    delete[] temp; //Почистим темп

    cout<<"Строка-колонка "<<slw<<" >"<<SlW[slw]<<endl; //Для отладки (!)
    slw++; //Увеличим счетчик строк

    //Приступим к новой строке
    SlW[slw] = new char[width+1]; //Выделим память для новой строки
    memset(SlW[slw],0,width+1); //Обнулим эту память
    strcat(SlW[slw],Sl[i]); //Запишим
    strcat(SlW[slw]," "); //Поставим проблел
    }
    }

    cout<<"Строка-колонка "<<slw<<" >"<<SlW[slw]<<endl; //Для отладки (!)

    system("pause");
    //Ну и самый конец вывод колонок в удобочитаемом виде (ни с лева на право), а с верху вниз + переход на право
    cout<<endl<<"\t\tИТОГОВЫЙ ВЫВОД:"<<endl;
    //Сначало нам нужно найти некую точку, по отношение к которой мы можем ориентироваться в массиве
    //Я посчитал, что отношение кол-ва слов к к кол-ву колонок то что нужно
    int st = st=((int)slw/Column)+1;
    for (int i =0; i<st; i++) // Обойдем слова кол-во слов +
    {
    for (int j=0; j<Column;j++)
    {
    if ((i+j*st)<=slw)
    cout<<SlW[i+j*st];
    if (j+1 != Column) cout<<"\t";
    }
    cout<<endl;
    }


    }
     
  5. Andersen1313

    Andersen1313 New Member

    Регистрация:
    18 окт 2010
    Сообщения:
    4
    Симпатии:
    0
    Я пробую на RAD Studio 2010 C++ Builder 2010 запустить и мне пишут ошибки:

    [ILINK32 Error] Error: Unresolved external '__InitVCL' referenced from C:\PROGRAM FILES\EMBARCADERO\RAD STUDIO\7.0\LIB\CP32MTI.LIB|crtlvcl
    [ILINK32 Error] Error: Unresolved external '__ExitVCL' referenced from C:\PROGRAM FILES\EMBARCADERO\RAD STUDIO\7.0\LIB\CP32MTI.LIB|crtlvcl
    [ILINK32 Error] Error: Unable to perform link

    Помогите разобраться...
     
  6. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Зайди в: File -> New -> Other -> Console Wizard. Убери галку с "Использовать VCL" (Use VCL). Галка на "Console Application" стоять должна. На "Multi Threaded" и "Use CLX" галка должна быть снята.
     
Загрузка...

Поделиться этой страницей