Possíveis razões para falhar?
-
22-09-2019 - |
Pergunta
ifstream::tellg()
está retornando -13 para um determinado arquivo.
Basicamente, escrevi um utilitário que analisa algum código -fonte; Abro todos os arquivos em ordem alfabética, começo com "Apple.cpp" e funciona perfeitamente ... mas quando chega ao "conversion.cpp", sempre no mesmo arquivo, depois de ler uma linha com sucesso, o retorna -13.
O código em questão é:
for (int i = 0; i < files.size(); ++i) { /* For each .cpp and .h file */
TextIFile f(files[i]);
while (!f.AtEof()) // When it gets to conversion.cpp (not on the others)
// first is always successful, second always fails
lines.push_back(f.ReadLine());
O código para AtEof
é:
bool AtEof() {
if (mFile.tellg() < 0)
FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
if (mFile.tellg() >= GetSize())
return true;
return false;
}
Depois de ler com sucesso a primeira linha de conversão.cpp, ela sempre trava com DEBUG - tellg(): -13
.
Este é o todo TextIFile
Classe (escreveu por mim, o erro pode estar lá):
class TextIFile
{
public:
TextIFile(const string& path) : mPath(path), mSize(0) {
mFile.open(path.c_str(), std::ios::in);
if (!mFile.is_open())
FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno));
}
string GetPath() const { return mPath; }
size_t GetSize() { if (mSize) return mSize; const size_t current_position = mFile.tellg(); mFile.seekg(0, std::ios::end); mSize = mFile.tellg(); mFile.seekg(current_position); return mSize; }
bool AtEof() {
if (mFile.tellg() < 0)
FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
if (mFile.tellg() >= GetSize())
return true;
return false;
}
string ReadLine() {
string ret;
getline(mFile, ret);
CheckErrors();
return ret;
}
string ReadWhole() {
string ret((std::istreambuf_iterator<char>(mFile)), std::istreambuf_iterator<char>());
CheckErrors();
return ret;
}
private:
void CheckErrors() {
if (!mFile.good())
FATAL(format("An error has occured while performing an I/O operation on %s") % mPath);
}
const string mPath;
ifstream mFile;
size_t mSize;
};
A plataforma é Visual Studio, 32 bits, Windows.
Editar: Funciona no Linux.
Editar: Encontrei a causa: terminações de linha. Tanto a conversão quanto o GUID e outros tinham n em vez de r n. Eu os salvei com r n e funcionou. Ainda assim, isso não deve acontecer, não é?
Solução
É difícil adivinhar sem saber exatamente o que está em Conversion.cpp
. No entanto, usando <
com as posições do fluxo não é definido pelo padrão. Você pode considerar um elenco explícito para o tipo inteiro correto antes de formatá -lo; Eu não sei que formatação FATAL
e format()
Espere executar ou como o %
O operador está sobrecarregado. As posições do fluxo não precisam mapear de maneira predicável para inteiros, certamente não se o arquivo não for aberto no modo binário.
Você pode querer considerar uma implementação alternativa para AtEof()
. Diga algo como:
bool AtEof()
{
return mFile.peek() == ifstream::traits_type::eof();
}