2015-01-23 1 views
1

У меня есть два текстовых файла, каждый с неизвестным числом целых чисел, отсортированных от самого низкого до самого высокого ... например:Запись отсортированных чисел из функции в текстовый файл?

входного файла 1: 1 3 5 7 9 11 ...
входной файл 2 : 2 4 6 8 10 ....

Я хочу взять эти цифры из обоих файлов, сортировать от низкого до высокого и затем выводить полный список отсортированных номеров из обоих входных файлов в один выходной файл , То, что я до сих пор ...

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include "iosort.h" 

int main() 
{ 
    const char* filename1 = "numberlist1.txt"; 
    const char* filename2 = "numberlist2.txt"; 
    std::ofstream ofs("output.txt"); 
    std::ifstream ifs1, ifs2; 
    std::string input1, input2; 

    ifs1.open(filename1); 
    std::getline(ifs1, input1); 
    std::cout << "Contents of file 1: " << input1 << std::endl; 

    ifs2.open(filename2); 
    std::getline(ifs2, input2); 
    std::cout << "Contents of file 2: " << input2 << std::endl; 

    ioSort(ifs1, ifs2, ofs); 


    return 0; 
} 

и моя функция ...

#include <fstream> 
#include <sstream> 
#include <vector> 
#include "iosort.h" 

void ioSort(std::ifstream& in1, std::ifstream& in2, std::ofstream& out) 
{ 

    int a, b; 
    std::vector<int> f1, f2, f3; //create one vector for each input stream 

    while (in1 >> a) 
    { 
     f1.push_back(a); 
    } 

    while (in2 >> b) 
    { 
     f2.push_back(b); 
    } 

    //now f1 and f2 are vectors that have the numbers from the input files 
    //we know that in these input files numbers are sorted from low to high 

    if (f1.size() > f2.size()) //input stream 1 was larger 
    { 
     for (int i = 0; i < f2.size(); i++) 
     { 
      if (f1[i] > f2[i]) //number at input vector 2 less that respective pos 
      {     //in input vector 1 
       f3.push_back(f2[i]); 
      } 
      else if(f1[i] == f2[i]) //numbers are equal 
      { 
       f3.push_back(f1[i]); 
       f3.push_back(f2[i]); 
      } 
      else //number in 1 is less than that in vector 2 
      { 
       f3.push_back(f1[i]); 
      } 
     } 

     for (int i = f2.size(); i < f1.size(); i++) 
     { 
      f3.push_back(f1[i]); //push remaining numbers from stream 1 into vector 
     } 
    } 
    else //input stream 2 was larger 
    { 
     for (int i = 0; i < f1.size(); i++) 
     { 
      if (f1[i] > f2[i]) //number at input vector 2 less that respective pos 
      {     //in input vector 1 
       f3.push_back(f2[i]); 
      } 
      else if(f1[i] == f2[i]) //numbers are equal 
      { 
       f3.push_back(f1[i]); 
       f3.push_back(f2[i]); 
      } 
      else //number in 1 is less than that in vector 2 
      { 
       f3.push_back(f1[i]); 
      } 
     } 

     for (int i = f1.size(); i < f2.size(); i++) 
     { 
      f3.push_back(f1[i]); //push remaining numbers from stream 2 into vector 
     } 

    } 

    //send vector contents to output file 
    for (int i = 0; i < f3.size(); i++) 
    { 
     out << f3[i] << " "; 
    } 


} 

Everytime я скомпилировать и запустить файл output.txt создается, но он пуст. Может кто-нибудь указать мне, что я делаю неправильно. Если, в основном, я делаю что-то вроде:

out << 8 << " " << 9 << std::endl; 

затем он будет отображаться в выходном файле.

+1

что делает отладчик говорят, что происходит в вашей фазе слияния – pm100

+0

я закрывал OFS по возвращении из iosort - но то, вероятно, не является причиной, и положить Endl на него в iosort – pm100

+0

Put все числа из всех файлов в одном файле [std :: set] (http://en.cppreference.com/w/cpp/container/set) или [std :: multiset] (http: //en.cppreference. ком/ж/CPP/контейнер/мультимножеством). Они будут автоматически отсортированы для вас. – crayzeewulf

ответ

1

AHA! Найдена ваша ошибка. Вы открываете файл, затем читаете его непосредственно в stdout (где вы указываете содержимое вашего файла), а затем передаете тот же поток в свою функцию. Ты не сможешь это сделать. Всякий раз, когда вы читаете файл, поток перемещается дальше по файлу. К тому моменту, когда вы находитесь в своей функции сортировки, вы находитесь в конце файла, и поэтому числа не читаются!

Вам нужно удалить строки

std::getline(ifs1, input1); 
std::cout << "Contents of file 1: " << input1 << std::endl; 

и

std::getline(ifs2, input2); 
std::cout << "Contents of file 2: " << input2 << std::endl; 

Вместо печатать их после того, как вы сохранили их в векторе.

Я оставлю остальную часть своего ответа ниже, поскольку вам или потомству может понадобиться это.

Я не уверен, что происходит с проблемой выходного файла. Пройдите всю цепочку и посмотрите, где она не работает:

  1. После того, как вы прочитали свой файл, распечатайте f1 и f2 с помощью cout. Они там и что вы ожидаете? Если они есть, мы можем двигаться дальше.
  2. После того, как ваш алгоритм запущен, ваш f3 есть и что вы ожидаете? Если да, продолжайте!
  3. Это позволяет вам диагностировать точную строку, в которой ваш код не работает (т. Е. Не делает этого, что вы ожидаете от него), и вы знаете, что можете управлять всем, что вы проверили.
  4. Конечно, вместо использования cout вы можете запустить это в среде отладки и посмотреть, что происходит шаг за шагом, но если вы не знаете, как это сделать, это займет больше времени, чтобы сделать это, чтобы диагностировать вашу проблему в первый раз ,

У вас есть другие проблемы, хотя функция слияния имеет ошибки. В результате вы пропускаете определенные элементы, потому что вы используете только один индекс для обоих массивов.Подумайте об этом: вы только нажимаете один номер в свой выходной массив в f1[i] > f2[i] или f1[i] < f2[i], но вы отбрасываете оба раза, увеличивая i.

Вы можете взять цикл слияния и упростить его, а также зафиксировать свою ошибку :).

auto it = f1.cbegin(); 
auto jt = f2.cbegin(); 

while (it != f1.cend() && jt != f2.cend()) { 
    if (*it < *jt) f3.push_back(*jt++); //f2 was bigger, push f2>f3 and increment f2 index 
    else if (*it > *jt) f3.push_back(*it++); //f1 was bigger, push f1>f3 and increment f1 index 
    else { //implicit equals, only option left 
    f3.push_back(*jt++); 
    f3.push_back(*it++); 
    } 
} 

while (it != f1.cend()) f3.push_back(*it++); 
while (jt != f2.cend()) f3.push_back(*jt++); 

Итак, теперь f3 содержит отсортированный массив, отсортированный по времени O (m + n). Если вы делаете это ради обучения, я сначала попытаюсь исправить вашу ошибку, прежде чем переключиться на это.

Если вы хотите написать меньше кода и скорость, это не проблема, вы можете использовать <algorithm>, чтобы сделать это, но это ужасно O ((n + m) lg (n + m)).

auto it = f1.cbegin(); 
auto jt = f2.cbegin(); 

while (it != f1.cend()) f3.push_back(*it++); 
while (jt != f2.cend()) f3.push_back(*jt++); 

std::sort(f3.begin(), f3.end()); 
1

Для того, чтобы быть коротким:

#include <fstream> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    std::ifstream infile1("infile1.txt"); 
    std::ifstream infile2("infile2.txt"); 
    std::ofstream outfile("outfile.txt"); 

    std::merge(
     std::istream_iterator<int>{infile1}, std::istream_iterator<int>{}, 
     std::istream_iterator<int>{infile2}, std::istream_iterator<int>{}, 
     std::ostream_iterator<int>{outfile, " "} 
     ); 
} 

std::merge представляет собой алгоритм STL, что слияние двух отсортированных диапазонов в один отсортированном диапазоне. И диапазоны - это файлы для этого случая. Файлы рассматриваются как диапазоны с использованием std::istream_iterator<int>. Доступ к выходному файлу осуществляется в диапазоне от std::ostream_iterator<int>.

1

Поскольку вы читаете файл с std::getline() перед вызовом ioSort(), для функции сортировки нет ничего для чтения.

Вы можете перемотать назад в начало файла с seekg().

ifs1.clear(); 
ifs1.seekg(0, ifs1.beg); 
ifs2.clear(); 
ifs2.seekg(0, ifs1.beg); 
ioSort(ifs1, ifs2, ofs); 

См How to read same file twice in a row

Смежные вопросы