C++ Builder 5 (and command-line tools download) getline() istream.cc fix

By: Anthony Pryor

Abstract: Delimiter problem with getline()


Question:
If I code: cin.getline(str, 80); I have to hit Enter twice for input to be recognized. but, if I code: cin >> str; It is only necessary to hit Enter once. Why?
Answer:
This is a bug in the iostream library. It can be fixed easily by changing one of the source files. Here's a quick and easy work around: Edit the file istream.cc line #1241 (this is in the getline() function) Change the following two lines from: else if ( this->rdbuf()->sgetc() == delim ) this->rdbuf()->sbumpc(); \\ eat the delimiter to: else if ( c == delim ) ; \\ we've already extracted the delimiter Now, here is the important part. The RTL has the original (broken) istream.cc code compiled into it, so unless you feel like rebuilding the entire RTL (which can be done), you must force your fixed version of istream.cc to get compiled into your application by defining the symbol _RWSTD_COMPILE_INSTANTIATE prior to including <iostream>. This symbol will cause istream.cc to be brought in and re-compiled so the new changes will be visible. Please refer to the following test case: \\ BEGIN test.cpp #define _RWSTD_COMPILE_INSTANTIATE #include <iostream.h> int main (void) { char str[80]; cin.getline( str, sizeof( str ) ) ; return 0; } \\ END test.cpp Keep in mind that the definition of _RWSTD_COMPILE_INSTANTIATE will cause any and all .cc files, if they are being used, to be added and compiled. If you use any of the STL containers, the extra compilation of their associated .cc files will cause slightly longer compile times, and in the case of the dynamic RTL, will cause the resulting .EXE to be larger (since the .cc code will no longer be coming from the RTL DLL). To prevent this unnecessary recompilation add the following immediately after the inclusion of <iostream>. #undef _RWSTD_COMPILE_INSTANTIATE

Server Response from: ETNASC01