digitalmars.D.learn - string mixup problem with stdin.byLine
- torea (57/57) Aug 07 2016 Hi all,
- Dave Akers (9/10) Aug 07 2016 It's casting a char[] to and immutable(char)[], causing the
- torea (3/13) Aug 08 2016 Problem fixed!!
- Seb (6/26) Aug 08 2016 http://dlang.org/phobos/std_stdio.html#.File.byLine
- torea (4/14) Aug 10 2016 Duh... I've read the documentation but managed to jump over these
- Meta (7/22) Aug 08 2016 Alternatively you can use std.stdio.byLineCopy and don't need to
- torea (2/8) Aug 10 2016 Thanks for the additional tip!
Hi all, I'm still at beginner level in D and trying to make a simple note program in the terminal. I've been struggling with a simple problem for the last 2 hours so I could use some help! What I want to do is: if I write #m, I record the following lines in a specific string member of a class, if I write #r, I record the following lines in another string member. Here is the problematic part of my code : bool stop = false; auto enr = new Enreg(); // class Enreg{ public: string motsCles; string resume; } enr.motsCles = ""; bool mode_motsCles = false; bool mode_resume = false; foreach( line; stdin.byLine ) { writeln( enr.motsCles ); // modified when I pressed #r <enter> string cleanLine = strip( cast(string)line ); string[] words = split( cleanLine ); // la phrase est separee en mots switch( words[0] ){ stop = true; break; case "#m": mode_motsCles = true; mode_resume = false; enr.motsCles = ""; break; case "#r": mode_resume = true; mode_motsCles = false; enr.resume = ""; break; default: break; } if( stop ) break; if( mode_motsCles ){ enr.motsCles = cleanLine; }else if( mode_resume ){ enr.resume ~= cleanLine ~"\\n"; } writeln( enr.motsCles ); } when I press : #m <enter> things;stuffs; <enter> at the end of my foreach, i have enr.motsCles initialized correctly with "things;stuffs;" If I continue with : #r <enter> enr.motsCles is modified at the very beginning of the loop and contain "#r\nings;stuffs;" Anyone has an idea about what's going bad with my code?
Aug 07 2016
I do believe your problem is with the line... On Monday, 8 August 2016 at 02:44:20 UTC, torea wrote:string cleanLine = strip( cast(string)line );It's casting a char[] to and immutable(char)[], causing the mutable buffer from byLine to be used as a string. what you want is... string cleanLine = strip( to!string(line) ); which should make a copy of the mutable buffer. I still a beginner at D but I think that will fix your problem. -Dave
Aug 07 2016
On Monday, 8 August 2016 at 05:17:24 UTC, Dave Akers wrote:I do believe your problem is with the line... On Monday, 8 August 2016 at 02:44:20 UTC, torea wrote:Problem fixed!! Thank you very much for the solution and the explanation!string cleanLine = strip( cast(string)line );It's casting a char[] to and immutable(char)[], causing the mutable buffer from byLine to be used as a string. what you want is... string cleanLine = strip( to!string(line) ); which should make a copy of the mutable buffer. I still a beginner at D but I think that will fix your problem. -Dave
Aug 08 2016
On Monday, 8 August 2016 at 07:09:55 UTC, torea wrote:On Monday, 8 August 2016 at 05:17:24 UTC, Dave Akers wrote:You should always carefully read the description and Notes ;-)I do believe your problem is with the line... On Monday, 8 August 2016 at 02:44:20 UTC, torea wrote:Problem fixed!! Thank you very much for the solution and the explanation!string cleanLine = strip( cast(string)line );It's casting a char[] to and immutable(char)[], causing the mutable buffer from byLine to be used as a string. what you want is... string cleanLine = strip( to!string(line) ); which should make a copy of the mutable buffer. I still a beginner at D but I think that will fix your problem. -DaveNote: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) when retention is needed. If the caller needs to retain a copy of every line, use the byLineCopy function instead.Unfortunately you are not the first one who bumped into this problem and this non intuitive behavior of byLine is heavily disputed.
Aug 08 2016
On Monday, 8 August 2016 at 12:29:51 UTC, Seb wrote:You should always carefully read the description and Notes ;-)Duh... I've read the documentation but managed to jump over these explanations... reading carefully would have saved me some pain! Hopefully I'll be more careful next time.Note: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) when retention is needed. If the caller needs to retain a copy of every line, use the byLineCopy function instead.Unfortunately you are not the first one who bumped into this problem and this non intuitive behavior of byLine is heavily disputed.
Aug 10 2016
On Monday, 8 August 2016 at 07:09:55 UTC, torea wrote:On Monday, 8 August 2016 at 05:17:24 UTC, Dave Akers wrote:Alternatively you can use std.stdio.byLineCopy and don't need to add the `to!string`. If you are calling to!string on ever line there will probably be no performance difference, but if you are not, such as only calling to!string on every *second* line or something like that, you should stick with byLine and calling to!string when needed.I do believe your problem is with the line... On Monday, 8 August 2016 at 02:44:20 UTC, torea wrote:Problem fixed!! Thank you very much for the solution and the explanation!string cleanLine = strip( cast(string)line );It's casting a char[] to and immutable(char)[], causing the mutable buffer from byLine to be used as a string. what you want is... string cleanLine = strip( to!string(line) ); which should make a copy of the mutable buffer. I still a beginner at D but I think that will fix your problem. -Dave
Aug 08 2016
On Monday, 8 August 2016 at 16:30:39 UTC, Meta wrote:Alternatively you can use std.stdio.byLineCopy and don't need to add the `to!string`. If you are calling to!string on ever line there will probably be no performance difference, but if you are not, such as only calling to!string on every *second* line or something like that, you should stick with byLine and calling to!string when needed.Thanks for the additional tip!
Aug 10 2016