-1

This is a part of my code. I don't know why the string was partially overwrite by another string.

for(int xd = 0 ; xd < 10; xd++)
            {
                if(booklist[xd].length() != 0)
                {
                    string d = string(booklist[xd]);
                    string e = "1,2,3,4";
                    string f = d + e;
                    cout << d.length() << endl;
                    cout << d << endl;
                    cout << f.length() << endl;
                    cout << f << endl;
                }
            }

The result of this code is:

16
brave new world
23
1,2,3,4ew world
28
nineteen eighty-four (1984)
35
1,2,3,4n eighty-four (1984)

I don't know why i got this wrong result. Could someone help me?

Kevin eyeson
  • 375
  • 4
  • 8
  • Did you use `valgrind`? This smells like either an invalid read or write somewhere. – Stephen Newell Mar 27 '18 at 15:55
  • 2
    We might be able to help you if you post your [MCVE], yes. – Lightness Races in Orbit Mar 27 '18 at 15:56
  • 2
    Read the Help Centre about how to ask a useful, completely self-contained question. Chiefly: (A) include a complete example that demonstrates the wrong behaviour, and (B) when telling readers it's wrong, be precise about why it's wrong and what would be right... This incomplete fragment will just lead to people asking multiple questions and speculating about what all the missing code is doing, which is nearly useless. – underscore_d Mar 27 '18 at 15:58

3 Answers3

3

Are you populating booklist by pulling from a file that you copied from Windows to a linux machine?

Windows will add a carriage return '\r' to the end of each line in addition to a newline. If you're reading from a windows file and using getline, it'll pull the carriage return into the string.

When a carriage return is output in the terminal, it resets the cursor to the beginning of the line, which would result in the behavior you're seeing.

To fix this, see this question on trimming whitespace from a string. The function you're looking for from that answer is rtrim (or "right trim"):

// trim from end (in place)
static inline void rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
        return !std::isspace(ch);
    }).base(), s.end());
}
scohe001
  • 15,110
  • 2
  • 31
  • 51
  • Only if your stream is in binary mode – Lightness Races in Orbit Mar 27 '18 at 15:58
  • yes, i just use 'getline' to put the line in to the booklist. what should i do? – Kevin eyeson Mar 27 '18 at 16:01
  • This was also my first thought. – Paul Floyd Mar 27 '18 at 16:03
  • @LightnessRacesinOrbit I'm able to reproduce this on my machine (make a file on windows, copy to linux machine and run) and I'm using the default `openmode` for my `ifstream`. – scohe001 Mar 27 '18 at 16:06
  • @MIKUVOCALOID see the link in my answer. Follow the answers on that post to trim the whitespace from the right side of your string. – scohe001 Mar 27 '18 at 16:07
  • @scohe001: That's because you added a step ("copy to linux machine", and you did the copy in binary mode). – Lightness Races in Orbit Mar 27 '18 at 16:07
  • I don't know why you're assuming that the program is being run on Linux at all. – Lightness Races in Orbit Mar 27 '18 at 16:10
  • @LightnessRacesinOrbit I mean no offense, but I'd appreciate it if you would make the point you're trying to make instead of making vague passive statements like this one. You clearly think that my answer needs to be edited in some way--and I have no problem with editing it or being told I'm wrong (I use this site to learn by answering as much by reading answers!)--but I can't do that if you give me comments like this. – scohe001 Mar 27 '18 at 16:16
  • @scohe001: I don't see what's "vague" or "passive" about what I said. My opening comment specifically states what is missing from your answer. My previous comment specifically states which assumption I believe you're making that may not hold. If "comments like this" bother you then you are going to be very disappointed! – Lightness Races in Orbit Mar 27 '18 at 16:27
1

It's likely that your booklist entries have trailing carriage returns, causing line 4 (for instance) to print brave new world, return to column 1, and print 1,2,3,4 over it. (That's why the character count is greater on line 3 than line 1, despite the two lines having the same apparent length.)

Strip the trailing whitespace from booklist entries (or figure out why it's getting in there in the first place, and deal with that) and things should be fine.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
0

Yes i got the reason why it shows wrong. Just like what scohe001 said: when i use getline to put the file in to an array, it will add \r after each element, so i use substr to remove the \r .Now it get work. Thanks every one.

Kevin eyeson
  • 375
  • 4
  • 8
  • 1
    This is a bit of a hacky approach, and breaks if the file _isn't_ formed this way. It would be better to work out _why_ you have the wrong line terminator for your platform. Did you copy it from another platform? Or did you open it in binary mode on Windows? Then fix _that_ problem and let your program run its course as normal. – Lightness Races in Orbit Mar 27 '18 at 16:12