Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] сортировка файла


Автор: nefestim 26.3.2008, 15:47
Разработать консольные программы для потоковой загрузки в оперативную память 
содержимого текстового файла, выполнения манипуляций над ним и потокового вывода 
полученных данных в другой файл. 
Первая программа должна использовать классы из стандартной библиотеки (iostream или
fstream) и для хранения в оперативной памяти использовать динамический массивы,
так чтобы отведенная память была пропорциональна размеру исходного файла.
Вторая программа должна дополнительно использовать класс vector из стандартной 
библиотеки для хранения данных в оперативной памяти и выполнения манипуляций 
над ними.

задание: Отбросить все символы в строках с номером символа менее 10 и затем 
    отсортировать строки в алфавитном порядке.

Автор: Rififi 26.3.2008, 17:11
Второй вариант (stl-way):

Код

#include <vector>
#include <string>
#include <fstream>
#include <functional>
#include <algorithm>

typedef std::vector<std::string> lines;

struct line
{
    friend std::istream& operator>>(std::istream& s, line& l)
    {
        std::getline(s, l.buf_);
        return (s);
    }
    operator const std::string () const { return (buf_); }
    std::string buf_;
};

// Прочитать файл в массив строк
lines read_file(const std::string& fileName)
{
    lines ls;
    std::ifstream ifs(fileName.c_str());
    std::copy(
        std::istream_iterator<line>(ifs),
        std::istream_iterator<line>(),
        std::back_inserter(ls));
    return (ls);
}

// Записать масив строк в файл
void write_file(const std::string& fileName, const lines& ls)
{
    std::ofstream ofs(fileName.c_str());
    std::copy(ls.begin(), ls.end(),
        std::ostream_iterator<lines::value_type>(ofs, "\n")        
        );
}

// Функтор для удаления символов с кодом меньше чем указанный
struct less_ch
{
    less_ch(std::string::value_type ch) : ch_(ch) {}
    
    template <typename U>
    void operator()(U& val) const
    {
        val.erase(
            std::remove_if(val.begin(), val.end(), std::bind2nd(std::less<typename U::value_type>(), ch_)),
            val.end());
    }
    std::string::value_type ch_;
};

int main()
{
    lines ls = read_file("in.txt");
    std::for_each(ls.begin(), ls.end(), less_ch(10)); // отсеивание
    std::sort(ls.begin(), ls.end()); // сортировка
    write_file("out.txt", ls);
    return (0);
}

Автор: nefestim 26.3.2008, 19:28
23 D:\Ðàçíîå\labs2\main.cpp `istream_iterator' is not a member of `std' 

std::istream_iterator<line>(ifs), - не понравилось компилятору, может компилятор тупой?

Но вот эти у меня работают:
Код

1 вариант:
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int count_strings ();        //Число строк в файле

int main (void){
  int i;
  char **str_arr, str[255];
  
  //Чтение
  str_arr = new char *[count_strings()];

  ifstream in_file("input.txt");
  if (!in_file){ cout << "Failed to open 'input.txt'"; return -1;}
  
  for (i = 0; !in_file.eof(); i++){
    in_file.getline(str, 254);
    str_arr[i] = new char[strlen(str) + 1];
    strcpy(str_arr[i], str);
  }
  in_file.close();
  
  
  //Запись
  ofstream out_file("output.txt");
  if (!out_file){ cout << "Failed to open 'output.txt'"; return -1;}
  
  for (int j = i - 1; j >= 0; j--) if (str_arr[j][0] < 48 || str_arr[j][0] > 57) out_file << str_arr[j] << endl;
  
  out_file.close();
  
  //Очистка
 // for (int j = 0; j < i; j++) delete [] str_arr[j];
  //delete [] str_arr;

  return 0;
}

//Число строк в файле
int count_strings (){
  int i;
  char ch;
  
  ifstream in_file("input.txt");
  if (!in_file){ cout << "Failed to open 'input.txt'"; return -1;}
  
  in_file.get(ch);
  for (i = 0; !in_file.eof();){
    if (ch == '\n') i++;
    in_file.get(ch);
  }
  
  in_file.close();
  return i + 1;
}



и 2 вариант:
Код

#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main (void){
  vector<string> str_arr;
  char str[255];
  
  ifstream in_file("input.txt");
  if (!in_file){ cout << "Failed to open 'input.txt'"; return -1;}
  
  //Чтение
  while (!in_file.eof()){
    in_file.getline(str, 254);
    str_arr.push_back (str);
  }
  
  in_file.close();
  
  //Запись
  ofstream out_file("output.txt");
  if (!out_file){ cout << "Failed to open 'output.txt'"; return -1;}
  
  for (vector<string>::iterator it = str_arr.end() - 1; it > str_arr.begin(); it--) 
    if ((*it).at(0) < 48 || (*it).at(0) > 57) out_file << (*it).c_str() << endl;
    
  out_file.close();
  return 0;
}



Но эта программа:
Разработать консольные программы для потоковой загрузки в оперативную память содержимого текстового файла, выполнения манипуляций над ним и потокового вывода полученных данных в другой файл.
Строки в новом файле должны быть в обратном порядке, причем выводить только  те строки, которые не начинаются с цифры.

Автор: Rififi 26.3.2008, 20:12
nefestim, 

Цитата
std::istream_iterator<line>(ifs), - не понравилось компилятору, может компилятор тупой?

#include <iterator>

Цитата
Строки в новом файле должны быть в обратном порядке, причем выводить только  те строки, которые не начинаются с цифры.

с учётом того, что большая часть работы уже проделана, пишем функтор:

Код
#include <locale>

template <typename T>
struct if_start_with_digit : public std::unary_function<T, bool>
{
    result_type operator()(const argument_type& s) const
    {
        // проверяем на цифру в первой позиции непустой строки
        return s.size() && std::isdigit(s[0], std::locale(""));
    }
};

тогда:
Код

    lines ls = read_file("in.txt");
    ls.erase(
        std::remove_if(ls.begin(), ls.end(), if_start_with_digit<lines::value_type>()),
        ls.end());
    std::reverse(ls.begin(), ls.end());
    write_lines("out.txt", ls);


Автор: nefestim 26.3.2008, 20:26
а первый вариант ни как не переделать под моё задание?

Автор: Rififi 26.3.2008, 21:24
можно, но... это старый добрый "old-school" стиль, со всеми его преимуществами и недостатками.
более громоздкий код, больше тонкостей и подводных камней, больше соблазнов сделать кривой хак "шоб хоть как-то работало"... пожалуй не буду я себя искушать (:

Автор: nefestim 26.3.2008, 21:41
Да вот и задание в разных вариантах. 

Но ладно хоть на этом спасибо. 

Автор: nefestim 2.4.2008, 21:26
Программа почемуто наоборот работает, все цифры скидывает в файл. А буквы удаляет. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)