Is There a C++ Iterator That Can Iterate Over a File Line by Line

Is there a C++ iterator that can iterate over a file line by line?

EDIT: This same trick was already posted by someone else in a previous thread.

It is easy to have std::istream_iterator do what you want:

namespace detail 
{
class Line : std::string
{
friend std::istream & operator>>(std::istream & is, Line & line)
{
return std::getline(is, line);
}
};
}

template<class OutIt>
void read_lines(std::istream& is, OutIt dest)
{
typedef std::istream_iterator<detail::Line> InIt;
std::copy(InIt(is), InIt(), dest);
}

int main()
{
std::vector<std::string> v;
read_lines(std::cin, std::back_inserter(v));

return 0;
}

Iterate through a file lines in python

The simplest:

with open('topology_list.txt') as topo_file:
for line in topo_file:
print line, # The comma to suppress the extra new line char

Yes, you can iterate through the file handle, no need to call readlines(). This way, on large files, you don't have to read all the lines (that's what readlines() does) at once.

Note that the line variable will contain the trailing new line character, e.g. "this is a line\n"

Read lines from file, iterate over each line and each character in that line

This works:

use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;

fn is_vowel(x: &char) -> bool {
"aAeEiIoOuU".chars().any(|y| y == *x)
}

fn is_umlaut(x: &char) -> bool {
"äÄüÜöÖ".chars().any(|y| y == *x)
}

fn valid(line: &str) -> bool {
line.chars().all(|c| !is_vowel(&c)) && line.chars().filter(is_umlaut).fuse().nth(1).is_some()
}

fn main() {
// Create a path to the desired file
let path = Path::new("c.txt");
let display = path.display();
// Open the path in read-only mode, returns `io::Result<File>`
let file = match File::open(&path) {
Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
Ok(file) => file,
};
let reader = BufReader::new(file);
for line in reader.lines() {
match line {
Ok(line) => {
if valid(&line) {
println!("{}", line)
}
}
Err(e) => println!("ERROR: {}", e),
}
}
}

Iterating over the content of a text file line by line - is there a best practice? (vs. PMD's AssignmentInOperand)

I generally prefer the former. I don't generally like side-effects within a comparison, but this particular example is an idiom which is so common and so handy that I don't object to it.

(In C# there's a nicer option: a method to return an IEnumerable<string> which you can iterate over with foreach; that isn't as nice in Java because there's no auto-dispose at the end of an enhanced for loop... and also because you can't throw IOException from the iterator, which means you can't just make one a drop-in replacement for the other.)

To put it another way: the duplicate line issue bothers me more than the assignment-within-operand issue. I'm used to taking in this pattern at a glance - with the duplicate line version I need to stop and check that everything's in the right place. That's probably habit as much as anything else, but I don't think it's a problem.

how can I iterate through a text file by loop twice at the same time

Assuming that you are iterating over the file (t is f), you can use the next function to advance the file iterator within the loop.

lcuLogIn="C:\\Automation\\LcuLogs\\LCU_Log_6Ant_Test.log"
with open(lcuLogIn, 'r+') as f:
for line in f:
if line.startswith("1"):
for i in range(6):
# Advance file iterator
line = next(f)
if i == 0:
print "do something"
if i == 1:
print "do something"
if i == 2:
print "do something"
if i == 3:
print "do something"
if i == 4:
print "do something"
if i == 5:
print "do something"

If t is actually some other iterable, you can create an iterator using the iter function, and use that in the same way.

lcuLogIn="C:\\Automation\\LcuLogs\\LCU_Log_6Ant_Test.log"
with open(lcuLogIn, 'r+') as f:
it = iter(t)
for line in it:
if line.startswith("1"):
for i in range(6):
# Advance the iterator
line = next(it)
if i == 0:
print "do something"
if i == 1:
print "do something"
if i == 2:
print "do something"
if i == 3:
print "do something"
if i == 4:
print "do something"
if i == 5:
print "do something"

Python: Iterate through text file; return a different line than referenced in 'if' statement

Here's an example of what I suggested in the comments, to use a flag to cause different processing of the next line of the file.

import xlsxwriter as xl
import os
from os import listdir

api = 0
row = 1

worksheet = xl.Workbook(myfile.xlsx').add_worksheet()
worksheet.write(0, 0, 'API')
worksheet.write(0, 1, 'Line Number')

count = 0

with open('C:/Project/file.txt', 'r', encoding="utf8") as text:
flagged = False
for line in text:
count += 1
if flagged:
flagged = False
api = line.rstrip('"\n').lstrip('API,"')
worksheet.write(count + 1, 0, api)
worksheet.write(count + 1, 1, count + 1)
elif "API" in line and "77-003" in line: # fixed an error here
api = line.rstrip('"\n').lstrip('API,"')
worksheet.write(count, 0, api)
worksheet.write(count, 1, count)
elif "API" in line and "67025" not in line:
flagged = True
workbook.close()

How to combine reading a file line by line and iterating over each character in each line?

You need to handle the potential error that could arise from each IO operation, represented by an io::Result which can contain either the requested data or an error. There are different ways to handle errors.

One way is to just ignore them and read whatever data we can get.

The code shows how this can be done:

use std::io::{BufRead, BufReader};
use std::fs::File;

fn main() {
let file = File::open("chry.fa").expect("cannot open file");
let file = BufReader::new(file);
for line in file.lines().filter_map(|result| result.ok()) {
for c in line.chars() {
print!("{}", c);
}
}
}

The key points: file.lines() is an iterator that yields io::Result. In the filter_map, we convert the io::Result into an Option and filter any occurrences of None. We're then left with just plain lines (i.e. strings).



Related Topics



Leave a reply



Submit