Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 02, 2015 reading file byLine | ||||
---|---|---|---|---|
| ||||
Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? |
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namal | On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: > Hello, > > I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations. |
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote:
> On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote:
>> Hello,
>>
>> I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file?
>
> You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations.
>
> A way to do it is:
>
> void main() {
> auto f = File("myfile");
> string buffer;
>
> foreach (line ; f.byLine) {
> buffer ~= line;
> }
>
> f.close();
> writeln(buffer);
> }
>
> Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations.
Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char?
|
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namal | On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: > On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote: >> On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: >>> Hello, >>> >>> I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? >> >> You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. >> >> A way to do it is: >> >> void main() { >> auto f = File("myfile"); >> string buffer; >> >> foreach (line ; f.byLine) { >> buffer ~= line; >> } >> >> f.close(); >> writeln(buffer); >> } >> >> Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations. > > Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. Just like in C++: buffer = line; However, you can just use "line" instead of "buffer" then. The byLine does buffer internally, so it overwrites "line" on the next iteration of foreach. If you want to keep the line string, then make a copy "line.idup". > I also tried to append a line to an array of strings but it failed because the line is a char? Here is how to get an array of lines: import std.stdio; void main() { auto f = File("myfile"); string buffer[]; foreach (line ; f.byLine) { buffer ~= line.idup; } f.close(); writeln(buffer); } |
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namal | On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: > Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char? In D you can do as in C++: buffer = ""; // or a brand new string You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string: import std.conv; import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLine) buffer ~= line.to!string; // <- Here is the magic writeln(buffer); } |
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote:
> On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote:
>> Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char?
>
> In D you can do as in C++:
>
> buffer = ""; // or a brand new string
>
> You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using:
>
> buffer.init();
>
> When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string:
>
> import std.conv;
> import std.stdio;
>
> void main() {
> string[] buffer;
>
> foreach (line ; File("test.txt").byLine)
> buffer ~= line.to!string; // <- Here is the magic
>
> writeln(buffer);
> }
Actually, even if converting works, what qznc did is better in the case of file reading. And even better would be to use .byLineCopy which basically does the same thing as qznc's solution but more efficiently:
import std.stdio;
void main() {
string[] buffer;
foreach (line ; File("test.txt").byLineCopy)
buffer ~= line;
writeln(buffer);
}
|
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote:
> You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using:
>
> buffer.init();
Huh? That doesn't work... Instead, use:
buffer = buffer.init;
|
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | Thx guys, this helped alot. The next thing I want to do is read the file line by line and split the stream into words. I found this example of code that seems to do sort of something like it. How can I modyfy it so I can store the words in an array of strings? Is a => a.length the iterator range? import std.algorithm, std.stdio, std.string; // Count words in a file using ranges. void main() { auto file = File("file.txt"); // Open for reading const wordCount = file.byLine() // Read lines .map!split // Split into words .map!(a => a.length) // Count words per line .sum(); // Total word count writeln(wordCount); } |
September 02, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namal | On Wednesday, 2 September 2015 at 21:53:20 UTC, Namal wrote:
> Thx guys, this helped alot. The next thing I want to do is read the file line by line and split the stream into words. I found this example of code that seems to do sort of something like it. How can I modyfy it so I can store the words in an array of strings? Is a => a.length the iterator range?
>
>
> import std.algorithm, std.stdio, std.string;
> // Count words in a file using ranges.
> void main()
> {
> auto file = File("file.txt"); // Open for reading
> const wordCount = file.byLine() // Read lines
> .map!split // Split into words
> .map!(a => a.length) // Count words per line
> .sum(); // Total word count
> writeln(wordCount);
> }
I would do what you want like this
auto file = File("file.txt");
auto words = file.byLine() // you've all lines in range
.map!(a => a.split); // read each line, splitting it into words
// now you've a range, where each element is an array of words
The map!(a => a.split) line simply maps each element to the return value of a.split - this is the predicate.
The a => a.split syntax is a lambda expression that tells map what to do on each element.
|
September 03, 2015 Re: reading file byLine | ||||
---|---|---|---|---|
| ||||
Posted in reply to wobbles | On Wednesday, 2 September 2015 at 22:19:11 UTC, wobbles wrote: > On Wednesday, 2 September 2015 at 21:53:20 UTC, Namal wrote: >> Thx guys, this helped alot. The next thing I want to do is read the file line by line and split the stream into words. I found this example of code that seems to do sort of something like it. How can I modyfy it so I can store the words in an array of strings? Is a => a.length the iterator range? >> >> >> import std.algorithm, std.stdio, std.string; >> // Count words in a file using ranges. >> void main() >> { >> auto file = File("file.txt"); // Open for reading >> const wordCount = file.byLine() // Read lines >> .map!split // Split into words >> .map!(a => a.length) // Count words per line >> .sum(); // Total word count >> writeln(wordCount); >> } > > > I would do what you want like this > > auto file = File("file.txt"); > auto words = file.byLine() // you've all lines in range > .map!(a => a.split); // read each line, splitting it into words > // now you've a range, where each element is an array of words > > The map!(a => a.split) line simply maps each element to the return value of a.split - this is the predicate. > > The a => a.split syntax is a lambda expression that tells map what to do on each element. hello, just copy pasting this brought me those errors: ep18.d(10): Error: no property 'split' for type 'char[]' /usr/include/dmd/phobos/std/algorithm.d(427): instantiated from here: MapResult!(__lambda1, ByLine!(char, char)) ep18.d(10): instantiated from here: map!(ByLine!(char, char)) and then a long list to the end of my code Error: undefined identifier a |
Copyright © 1999-2021 by the D Language Foundation