2

Program:

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main(){
    double x;
    string name;
    while(cin >> name){
        cout<<name<<endl;
        while (cin >> x);
        cin.clear();
    }
}

Input:

Moo 100 100 100 100 100 100 100 100
Moore 75 85 77 59 0 85 75 89
Norman 57 78 73 66 78 70 88 89
Westerly 43 98 96 79 100 82 97 96
Edwards 77 72 73 80 90 93 75 90
Franklin 47 70 82 73 50 87 73 71
Jones 77 82 83 50 10 88 65 80
Carpenter 47 90 92 73 100 87 93 91

Output:

Moo
Moore
orman
Westerly
wards
ranklin
Jones
rpenter

I started working through the book accelerated C++ and ran into a piece of the authors code (chapter 4) that was not working as expected on my machine (the above sample is abbreviated but experiences the same problem as the code directly from the book). The intent is to print all the names from the beginning of the lines of numbers representing student grades in the input. What actually happens is that some of the names are printed in full while others, apparently at random, have letters missing from the start. I was hoping someone here could shed some light on why this is happening.

My initial thought was that in the process of failing on reaching non-numeric input the line:

 while (cin >> x);

was somehow overshooting the beginning of the next name but I am having difficulty testing this and I'm unsure of why that should happen.

Update: It seems I was experiencing the same issue as this question with the clang compiler for mac.

Community
  • 1
  • 1
yoto
  • 21
  • 2
  • 2
    [Looks fine to me](http://ideone.com/kxZJ2g). Whatever issue you're having doesn't involve the code or input that you're showing here. – Drew Dormann Jul 08 '14 at 19:40
  • Also check this one: [How to test whether stringstream operator>> has parsed a bad type and skip it](http://stackoverflow.com/questions/24504582/test-whether-stringstream-operator-has-parsed-a-bad-type?noredirect=1#comment37965807_24504582) – πάντα ῥεῖ Jul 08 '14 at 19:45
  • @yoto How do you provide the input? I can suspect that the input is made from some file prepared by a text editor. – Vlad from Moscow Jul 08 '14 at 19:52
  • @VladfromMoscow Yes that's right I just used the line ./test <../../unix-source/data/grades (where grades is a text file containing the input). Is that likely to be the cause of the problem? – yoto Jul 08 '14 at 19:55
  • @yoto See my answer that I have already written. – Vlad from Moscow Jul 08 '14 at 19:56
  • 2
    This is clang bug [17782](http://llvm.org/bugs/show_bug.cgi?id=17782). – T.C. Jul 11 '14 at 03:35
  • 2
    [See here for further discussion](http://stackoverflow.com/questions/24689378/characters-extracted-by-istream-double). As T.C. points out, the Standard is defective, and libc++ and libstdc++ both have bugs in this area. Probably it is extracting `i`, `p`, `x`, `n` as those are valid characters that can appear in doubles (e.g. `"inf"`, `"NaN"`, `0x1234p-04`) however the Standard says that it's supposed to reject those characters (even though that doesn't make much sense), and also it should reject characters which don't actually lead to a valid `double` such as "Ed" in your case. – M.M Jul 11 '14 at 04:04
  • There's a very thorough writeup of this issue here: https://github.com/tardate/LittleCodingKata/tree/master/cpp/DoubleTrouble – orthocresol Jul 10 '22 at 13:50

1 Answers1

0

i can only suspect that the input is done from some file that was prepared by using a text editor that inserts some control symbols in the text. It seems for example that the text editor you used inserts backspace characters in the text.

Use a text editor that does not insert any control symbols in text.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Ah, your probably right I'll look into that and see if I can fix it. Initially the text file was downloaded straight from the books website so it seems strange that it would contain control symbols but in retrospect that seems the most likely explanation. Thank you. – yoto Jul 08 '14 at 20:00
  • Looking into it further it seems this wasn't actually the issue. It seems the implementation I'm using just throws out certain letters when you try to do cin >> x on them (where x is a double), even though the input fails. I tested it a bit and it seems to throw out a,b,c,d,e,f,i,n,p,x but leaves everything else. Maybe it has something to do with trying to interpret the input as hexadecimal, I'm not sure. – yoto Jul 08 '14 at 23:08
  • I did, part of it anyway, heres the results for 2 names. Same program but this time with input entered by hand. ./test Moo 100 100 100 100 100 100 100 Moo Edwards 77 72 73 80 90 93 75 90 wards – yoto Jul 08 '14 at 23:38
  • @yoto Try to enter only the line with Edwards. – Vlad from Moscow Jul 08 '14 at 23:48
  • In that case it does work but only if Edwards is the first thing read (i.e. if cin >> x is never applied to it) – yoto Jul 08 '14 at 23:53
  • @yoto What key do you press after entered input? – Vlad from Moscow Jul 09 '14 at 03:49
  • The return key, I'm on a macbook if that means anything. – yoto Jul 09 '14 at 04:07
  • @yoto It seems that the system uses Unicode characters. So you should try to use wide strings std::wstring and correspondingly std::wcout and so on. – Vlad from Moscow Jul 09 '14 at 12:33
  • I tried rewriting the program above with the wide types. The same behaviour persists. Interestingly, I found that changing x from a double to an int eliminates the issue completely. I'm interested to know what's going on here. – yoto Jul 10 '14 at 05:11
  • @yoto hex-dump your text file and look for any odd characters – M.M Jul 11 '14 at 01:45