Нужно написать конкретные строки текста в новый текст - PullRequest
0 голосов
/ 05 августа 2011

У меня есть числовые строки текстовых данных размером от 1 до 150 мегабайт, мне нужно написать строки чисел, относящихся к высоте, например: высота = 4, новый текст должен содержать строки: 1,5,9,13, 17,21 .... последовательно.

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

Я очистил код в соответствии с рекомендациями. Теперь он пишет все строки sample2 text, все сделано здесь. Спасибо всем

Я открыт для изменения метода, пока он доставляет то, что мне нужно, спасибо за ваше время и помощь.

вот что у меня есть:

#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <vector>

using namespace std;

int h,n,m;
int c=1;

int main () {

cout<< "Enter Number Of Heights: ";
cin>>h;

ifstream myfile_in ("C:\\sample.txt");
ofstream myfile_out ("C:\\sample2.txt");
string line;
std::string str;
vector <string> v;
if (myfile_in.is_open()) {
myfile_in >> noskipws;
int i=0;
int j=0;
while (std::getline(myfile_in, line)) {
v.push_back( line );
++n;
if (n-1==i) {
myfile_out<<v[i]<<endl;
i=i+h;
++j;
}
    }
cout<<"Number of lines in text file: "<<n<<endl;
}

else cout << "Unable to open file(s) ";

cout<< "Reaching here, Writing one line"<<endl;

system("PAUSE");
return 0; 
}

Ответы [ 3 ]

0 голосов
/ 05 августа 2011

Если для C ++ нет абсолютно веской причины, вы используете для этого не тот язык программирования. В awk вся ваша программа:

{ if ( FNR % 4 == 1 ) print; }

Или, давая всю командную строку, например в ш фильтровать строки 1,5,9,13, ...:

awk '{ if ( FNR % 4 == 1 ) print; }' a.txt > b.txt
0 голосов
/ 05 августа 2011

Несколько вещей.

Сначала вы полностью прочитали файл, просто для того, чтобы сосчитать количество строк, а затем прочитали его во второй раз, чтобы обработать его, создав образ в памяти в v.Почему бы просто не прочитать его в первый раз, а сделать все остальное в образе памяти?(v.size() затем даст вам количество строк, поэтому вам не нужно их считать.)

И вы никогда не будете использовать счет в любом случае.

Во-вторых, как только выЕсли вы достигли конца файла в первый раз, устанавливается failbit;все дальнейшие операции не выполняются, пока он не будет сброшен.Если вам нужно прочитать файл дважды (скажем, потому что вы полностью отказались от v), то вы должны сделать myfile_in.clear() после первого цикла, но перед поиском в начале.

Вы только тестируетедля is_open после прочтения файла один раз.Этот тест должен быть выполнен сразу после открытия.

Вы также установили noskipws, хотя вы не выполняете никаких форматированных вводов, на которые это может повлиять.

Финальный while - этоочень подозреваемыйПоскольку вы не выполнили clear, вы, вероятно, никогда не войдете в цикл, но если вы это сделали, вы очень быстро начнете доступ за пределами: после прочтения n строк размер v будет равен n, ноВы читаете его с индексом i, который будет n * h.

Наконец, вы должны явно закрыть выходной файл и проверить на ошибки после закрытия, на всякий случай.

Мне не понятно, что вы пытаетесь сделать.Если все, что вы хотите сделать, это вставить h пустых строк между каждой существующей строкой, что-то вроде:

std::string separ( h + 1, '\n' );
std::string line;
while ( std::getline( myfile_in, line ) ) {
    myfile_out << line << separ;
}

должно помочь.Нет необходимости хранить полный ввод в памяти.(В этом отношении вам даже не нужно писать программу для этого. Что-то простое sed 's:$:\n\n\n\n:' < infile > outfile сделает свое дело.)

РЕДАКТИРОВАТЬ:

Читая другие ответы, япоймите, что я, возможно, неправильно понял проблему, и что он хочет выводить только каждую h -ю строку.Если это так:

std::string line;
while ( std::getline( myfile_in, line ) ) {
    myfile_out << line << '\n';
    for ( int count = h - 1; h > 0; -- h ) {
        std::getline( myfile_in, line );
        //  or myfile_in.ignore( INT_MAX, '\n' );
    }
}

Но опять же, другие инструменты кажутся более подходящими.(Я бы последовал совету Титона и использовал бы AWK.) Зачем писать программу на языке, который вы не очень хорошо знаете, когда инструменты для этой работы уже доступны.

0 голосов
/ 05 августа 2011

Вам нужно использовать seekg , чтобы установить позицию в начале файла, как только вы прочитали его (вы прочитали его один раз, чтобы посчитать строки (что я не думаю, вам действительно нужно, так как этот размер никогда не используется, по крайней мере, в этом фрагменте кода)

А какой смысл, если внутренний while? На каждом цикле у вас есть

int i=1;
myfile_out<<v[i]; //Not writing to text
i=i+h;

Таким образом, в каждом цикле i получает 1, поэтому вы выводите элемент с индексом 1 все время. Это не первый элемент, так как индексы начинаются с 0. Итак, как только вы поставите seekg или удалите первый while, ваша программа начнет аварийно завершать работу.

Итак, i начинайте с 0. И вытащите его из двух while петель, прямо в начале if-statement.

Ах, второй while тоже не нужен. Оставь только первый.


EDIT: Добавить

myfile_in.clear();

до seekg для очистки флагов.

Кроме того, ваш алгоритм неверен. Вы получите ошибку сегмента, если h> 1, потому что вы выйдете за пределы диапазона (вектора). Я бы посоветовал сделать это так: прочитайте файл в while, который считает строки. И сохранить каждую строку в векторе. Таким образом, вы сможете удалить второе чтение, seekg, clear и т. Д. Кроме того, поскольку вы уже сохраняете содержимое файла в vector, вы ничего не потеряете. Тогда просто используйте цикл for с шагом h.


Снова отредактируйте, относительно вашего редактирования: нет, это не имеет ничего общего с флагами. if, где вы сравниваете i==j, вне времени. Добавьте это внутрь. Кроме того, увеличьте j за пределы if. Или просто удалите j и используйте вместо него n-1. Как

if ( n-1 == i )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...