2016-03-19 3 views
1

Я все еще новичок в программировании на С ++, и я знаю, что мой код очень неэффективен, поэтому, пожалуйста, расскажите мне, как я пишу эту программу для изучения финала, который подходит скоро.Слияние двух текстовых файлов на один дает другой вывод

Один из текстовых файлов rainfallToDate.txt, и она имеет:

0.01 
1.74 
0.19 
0.65 
0.50 
0.10 
0.00 
0.02 
0.01 
0.06 
1.57 
7.76 

, а другой averageRainfall.txt:

2.99 
3.32 
2.04 
1.06 
0.39 
0.09 
0.00 
0.00 
0.23 
0.78 
1.88 
2.12 

Я должен объединить эти два текстовых файла в текстовый файл с именем rainfall.txt

Вот пример вывода:

Rainfall for Cupertino: A Comparison 

Month Average 2015  

1  2.99  0.01   
2  3.32  1.74  
3  2.04  0.19  
4  1.06  0.65  
5  0.39  0.50  
6  0.09  0.10  
7  0.00  0.00  
8  0.00  0.02  
9  0.23  0.01  
10  0.78  0.06  
11  1.88  1.57  
12  2.12  7.76  

Как вы можете видеть averageRainfall.txt хранится в строке «среднее», а другой текстовый файл rainfallToDate.txt хранится в 2015.

Ну вот, что я до сих пор, и моя попытка " слияние "двух текстовых файлов.

Моей попытка:

#include <iostream> // for cout 
#include <fstream> // for file I/O 
#include <cstdlib> // for exit() 

using namespace std; 

int main() 
{ 
ifstream fin; 
ofstream fout; 

if (fin.fail()) 
{ 
    cout << "Input file failed to open.\n"; 
    exit(-1); 
} 
fout.open("rainfall.txt"); 
if (fout.fail()) 
{ 
    cout << "Output file failed to open.\n"; 
    exit(-1); 
} 

fout << "Rainfall for Cupertino: A Comparison\n" << endl; 
fout << "Month\tAverage\t 2015\tDeficit\n" << endl; 

    for (int i = 1; i <= 12; i++) { // counts the month from 1-12 

    fout << fixed << i << endl; 

} 
fin.close(); 
fout.close(); 


// averageRainfall under averages 
ifstream average; 
ofstream oaverage; 
average.open("averageRainfall.txt"); 
if (average.fail()) 
{ 
    cout << "Input file failed to open.\n"; 
    exit(-1); 
} 
oaverage.open("rainfall.txt"); 
if (fout.fail()) 
{ 
    cout << "Output file failed to open.\n"; 
    exit(-1); 
} 

oaverage << "\t" << average; 


// rainfallToDate under 2015 
average.close(); 
oaverage.close(); 

ifstream ToDate; 
ofstream oToDate; 
ToDate.open("rainfallToDate.txt"); 
if (ToDate.fail()) 
{ 
    cout << "Input file failed to open.\n"; 
    exit(-1); 
} 
oToDate.open("rainfall.txt"); 
if (oToDate.fail()) 
{ 
    cout << "Output file failed to open.\n"; 
    exit(-1); 
} 

oToDate << "\t" << "\t" << ToDate; 

ToDate.close(); 
oToDate.close(); 

return 0; 
} 

Теперь проблемы, прогоны коды и все не устанавливает какое-либо ошибки, однако, когда я открываю файл, где и код сливает файлы распечатывает

0x29fe64 

то, что я считаю, что я сделал неправильно, что я не ставил две TextFiles «средние» и «rainfalltodate» на две отдельные массивы и изложив его оттуда. Исправьте меня, если я ошибаюсь, не очень уверен, если я предположил, что двое поставили оба из них в два отдельных массива.

+0

Вы делаете много чего: вы открываете «rainfall.txt» для записи несколько раз, а режим по умолчанию - «усеченный» режим, который уничтожает существующий контент; у вас есть несколько переменных для одного и того же выходного файла, что бессмысленно, но ваша ошибка связана с тем, что вы «oToDate << ToDate» не копируете содержимое одного файла в другой, он просто печатает адрес объекта «ToDate» в « oToDate». – kfsone

ответ

1
oToDate << "\t" << "\t" << ToDate; 

Я думаю, ваше намерение здесь чтобы скопировать все из потока ToDate в поток oToDate, но это не совсем то, что происходит. Вместо этого это просто попытка выписать одно значение, которое представляет ToDate, что оказывается (бессмысленным) адресом указателя переменной.

Однако, даже если мы исправим это, мы не можем делать то, что вы хотите в данный момент. Похоже, вы пытаетесь первыми скопировать средние данные о осадках, а затем на втором пропуске пропустите то, что вы только что написали, и поставьте осадку на место рядом с ним. Но это не сработает - второй проход просто перепишет существующую строку.

Вместо этого вам нужно загрузить оба набора данных и записать их за один раз. Один из вариантов состоит в том, чтобы загрузить два набора данных отдельно и использовать std::vector для хранения значений перед их записью. Давайте посмотрим, как мы можем это сделать:

std::ifstream average{"averageRainfall.txt"}; 
std::vector<double> average_data; 

std::copy(std::istream_iterator<double>{average}, 
      std::istream_iterator<double>{}, 
      std::back_inserter(average_data)); 

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

Затем нам необходимо записать оба значения в файл одновременно. Во-первых, мы открываем выходной файл:

std::ofstream rainfall{"rainfall.txt"}; 

Затем цикл через два вектора, копирование данных в выходной поток:

auto last = std::min(average_data.size(), to_date_data.size()); 

for (int i = 0; i < last; i++) { 
    rainfall << average_data[i] << "\t" << to_date_data[i] << "\n"; 
} 

и вы все сделали :-)

0

Ваш странный выход поступает из этой линии:

oaverage << "\t" << average; 

average представляет собой поток, а не числовое значение. Когда вы пытаетесь распечатать поток, поток заканчивается преобразованием в указатель, и вместо этого вы видите значение указателя.

Там Похожая проблема на этой линии:

oToDate << "\t" << "\t" << ToDate; 
0

может быть, вы должны прочитать некоторые основные C++ программирование книги, вот мой код:

#include <iostream> // for cout 
#include <fstream> // for file I/O 
#include <cstdlib> // for exit() 
using namespace std; 
int main() 
{ 
    std::ifstream fin_rain_date("rainfallToDate.txt"); 
    std::ifstream fin_rain_ave("averageRainfall.txt"); 
    if(fin_rain_ave==NULL||fin_rain_date==NULL) 
    { 
    std::cout<<"can not open file"<<std::endl; 
    } 
    std::ofstream fout("rainfall.txt"); 
    fout<<"Rainfall for Cupertino: A Comparison"<<std::endl; 
    fout<<"Month\tAverage\t 2015\tDeficit"<<std::endl; 
    for(int i=0;i<12;i++) 
    { 
    fout<<i<<"\t"; 
    char tmpstr[256]; 
    fin_rain_ave.getline(tmpstr,256); 
    fout<<tmpstr<<"\t"; 
    fin_rain_date.getline(tmpstr,256); 
    fout<<tmpstr<<std::endl; 
    } 
    return 0; 
}