In theory, these two command-lines should be equivalent:
1
type tmp.txt | test.exe
2
test.exe < tmp.txt
I have a process involving #1 that, for many years, worked just fine; at some point within the last year, we started to compile the program with a newer version of Visual Studio, and it now fails due to malformed input (see below). But #2 succeeds (no exception and we see expected output). Why would #2 succeed where #1 fails?
I've been able to reduce test.exe to the program below. Our input file has exactly one tab per line and uniformly uses CR/LF line endings. So this program should never write to stderr:
#include <iostream>
#include <string>
int __cdecl main(int argc, char** argv)
{
std::istream* pIs = &std::cin;
std::string line;
int lines = 0;
while (!(pIs->eof()))
{
if (!std::getline(*pIs, line))
{
break;
}
const char* pLine = line.c_str();
int tabs = 0;
while (pLine)
{
pLine = strchr(pLine, '\t');
if (pLine)
{
// move past the tab
pLine++;
tabs++;
}
}
if (tabs > 1)
{
std::cerr << "We lost a linebreak after " << lines << " good lines.\n";
lines = -1;
}
lines++;
}
return 0;
}
When run via #1, I get the following output, with the same numbers every time (in each case, it's because getline has returned two concatenated lines with no intervening linebreak); when run via #2, there's (correctly) no output:
We lost a linebreak after 8977 good lines.
We lost a linebreak after 1468 good lines.
We lost a linebreak after 20985 good lines.
We lost a linebreak after 6982 good lines.
We lost a linebreak after 1150 good lines.
We lost a linebreak after 276 good lines.
We lost a linebreak after 12076 good lines.
We lost a linebreak after 2072 good lines.
We lost a linebreak after 4576 good lines.
We lost a linebreak after 401 good lines.
We lost a linebreak after 6428 good lines.
We lost a linebreak after 7228 good lines.
We lost a linebreak after 931 good lines.
We lost a linebreak after 1240 good lines.
We lost a linebreak after 2432 good lines.
We lost a linebreak after 553 good lines.
We lost a linebreak after 6550 good lines.
We lost a linebreak after 1591 good lines.
We lost a linebreak after 55 good lines.
We lost a linebreak after 2428 good lines.
We lost a linebreak after 1475 good lines.
We lost a linebreak after 3866 good lines.
We lost a linebreak after 3000 good lines.
This turns out to be a known issue: