Содержимое файла file.txt:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
Где 5 3
- координатная пара.
Как обрабатывать эти данные по строкам в С++?
Я могу получить первую строку, но как получить следующую строку файла?
ofstream myfile;
myfile.open ("text.txt");
Сначала сделайте ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Два стандартных метода:
Предположим, что каждая строка состоит из двух чисел и токена чтения с помощью токена:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
Линейный синтаксический анализ, используя строковые потоки:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
Нельзя смешивать (1) и (2), так как разбор маркера не сожрает новые строки, поэтому вы можете получить ложные пустые строки, если вы используете getline()
после того, как извлечение на основе токена вы уже до конца строки.
Используйте ifstream
для чтения данных из файла:
std::ifstream input( "filename.ext" );
Если вам действительно нужно читать строки за строкой, сделайте следующее:
for( std::string line; getline( input, line ); )
{
...for each line in input...
}
Но вам, вероятно, просто нужно извлечь координатные пары:
int x, y;
input >> x >> y;
Update:
В вашем коде вы используете ofstream myfile;
, однако o
в ofstream
означает output
. Если вы хотите прочитать из файла (ввод), используйте ifstream
. Если вы хотите как читать, так и писать, используйте fstream
.
getline
находится в string
see , так что не забывайте #include <string>
Расширение принятого ответа, если вход:
1,NYC
2,ABQ
...
вы все равно сможете применить ту же логику, как это:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();
Так как ваши координаты принадлежат друг другу как пары, почему бы не написать для них структуру?
struct CoordinatePair
{
int x;
int y;
};
Затем вы можете написать перегруженный оператор извлечения для istreams:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
И тогда вы можете прочитать файл координат прямо в вектор:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Couldn't open " << filename << " for reading\n";
}
// Now you can work with the contents of v
}
int
токена из потока в operator>>
? Как можно заставить его работать с анализатором обратного отслеживания (т. Е. Когда operator>>
не работает, откатить поток до предыдущей позиции, в конце вернуть false или что-то в этом роде)?
int
токена, тогда поток is
будет иметь значение false
и цикл чтения прекратится в этой точке. Вы можете обнаружить это в operator>>
, проверив возвращаемое значение отдельных операций чтения. Если вы хотите откатить поток, вы должны вызвать is.clear()
.
с аргументами командной строки:
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include "print.h"
using namespace std;
int main (int argc, char *argv[])
{
vector<string> list;
ifstream in_stream;
string line;
in_stream.open(argv[1]);
while(!in_stream.eof())
{
in_stream >> line;
list.push_back(line);
}
in_stream.close();
print(list);
sort(list.begin(), list.end());
print(list);
}