ifstream as argument without reference
Oct 21, 2013 at 7:22pm UTC
How can I pass an ifstream argument without reference?
1 2 3 4 5 6 7 8 9 10 11
int main(void )
{
ifstream stream;
foo(stream);
}
// where foo is:
void foo(ifstream stream) // <-- (ifstream != ifstream &)
{
// do something with stream but don't affect main::stream
}
The problem is that: "void foo(fstream) { /*...*/ }" is illegal
Last edited on Oct 23, 2013 at 5:44pm UTC
Oct 21, 2013 at 7:24pm UTC
You cannot pass streams by value because streams are non-copyable. Why do you want to pass streams by value?
Oct 21, 2013 at 7:48pm UTC
With a conforming implementation (not the GNU offering), we can move a
std::ifstream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
#include <fstream>
#include <utility>
void foo( std::ifstream stm )
{
std::cout << stm.rdbuf() ;
}
int main()
{
foo( std::ifstream(__FILE__) ) ;
std::ifstream this_file(__FILE__) ;
foo( std::move(this_file) ) ;
}
Last edited on Oct 21, 2013 at 7:50pm UTC
Oct 21, 2013 at 8:17pm UTC
It seems OP wants to have two independent streams work on the same content (in this case the same file). @rodrigoloc why do you want this? It does't make much sense.
Oct 21, 2013 at 8:36pm UTC
> It seems OP wants to have two independent streams work on the same content (in this case the same file).
It is only for input operations.
Just use two different
std::ifstream objects; they don't interfere with each other.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#include <iostream>
#include <fstream>
#include <string>
void foo( const std::string& path_to_file )
{
std::ifstream file(path_to_file) ;
std::streamoff cnt = 0 ;
char ch ;
while ( file.get(ch) ) if ( ch == '\n' ) ++cnt ;
std::cout << "*** from foo: " << cnt << " newlines ***\n" ;
}
int main()
{
std::string path_to_file = __FILE__ ;
std::ifstream file(path_to_file) ;
std::string line ;
for ( int i = 0 ; i < 10 && std::getline(file,line) ; ++i )
std::cout << line << '\n' ;
std::cout << "\n-----------------------------\n" ;
foo(path_to_file) ;
std::cout << "-----------------------------\n" ;
while ( std::getline(file,line) ) std::cout << line << '\n' ;
}
http://coliru.stacked-crooked.com/a/df7fc9dfab76359b
Oct 23, 2013 at 4:13pm UTC
I did something like JLBorges but using istream::tellg and istream::seekg. Like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
void foo(string strFilename, streamoff nPosition)
{
ifstream InFile(strFilename);
InFile.seekg(nPosition);
// do something...
}
int main(void )
{
const string strFilename = "" ;
ifstream InFile(strFilename);
// do something...
auto nPosition = InFile.tellg();
foo(strFilename, nPosition);
// do something else... and so on
return 0;
}
But that doesn't work because ifstream::tellg returns negative numbers and they're diferent in every file I try.
Oct 23, 2013 at 4:29pm UTC
> ifstream::tellg returns negative numbers
tellg() returns a negative value pos_type(-1) on failure.
Perhaps it would help if you post the actual code.
Oct 23, 2013 at 4:39pm UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
ifstream InFile(strFilename);
if (InFile)
{
// ...
while (InFile)
{
string strCommand;
InFile >> strCommand;
if (strCommand == "this-is-a-string" )
{
streampos nFilePosition = InFile.tellg();
// nFilePositions gets negative values like -32 or -35
foo(strFilename, nFilePosition);
}
InFile.ignore(UINT32_MAX, '\n' );
}
InFile.close();
}
else
{
// Throw exception
}
Oct 23, 2013 at 5:02pm UTC
What does this print out?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
std::string strCommand;
while ( InFile >> strCommand )
{
if (strCommand == "this-is-a-string" )
{
std::streampos nFilePosition = InFile.tellg();
// nFilePositions gets negative values like -32 or -35
std::streamoff offset = nFilePosition ;
std::cout << offset << '\n' ;
foo(strFilename, nFilePosition);
}
InFile.ignore(UINT32_MAX, '\n' );
}
Oct 23, 2013 at 5:20pm UTC
That prints the same because streampos can be perfectly casted to streamoff.
But adding these two lines to the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
ifstream InFile(strFilename);
if (InFile)
{
// ...
while (InFile)
{
string strCommand;
cout << InFile.tellg() << endl; // <--
InFile >> strCommand;
cout << InFile.tellg() << endl; // <--
if (strCommand == "this-is-a-string" )
{
streampos nFilePosition = InFile.tellg();
// nFilePositions gets negative values like -32 or -35
foo(strFilename, nFilePosition);
}
InFile.ignore(UINT32_MAX, '\n' );
}
InFile.close();
}
else
{
// Throw exception
}
Prints something like this:
Oct 23, 2013 at 5:40pm UTC
Do not do this:
cout << InFile.tellg() << endl;
std::fpos is not a simple numeric type that can be printed out as a number.
http://en.cppreference.com/w/cpp/io/fpos
If you want to find out what the offset is,
a. convert the streampos to a streamoff
b. streamoff is a signed integral type, it can be printed out as a meaningful number.
Also, verify that the stream is in a good state before
tellg() ; or you would get
std::streampos(-1)
(which is not equal to a numeric value of -1; it represents an invalid position.)
1 2 3 4 5 6 7
if ( InFile >> strCommand ) // if the read succeeded
{
streampos nFilePosition = InFile.tellg();
// print out offset from beginning
std::cout << std::streamoff( nFilePosition ) << '\n' ;
}
Last edited on Oct 23, 2013 at 5:40pm UTC
Oct 23, 2013 at 5:51pm UTC
It keeps printing the same.
cout << streamoff(InFile.tellg()) << endl;
Oct 23, 2013 at 6:00pm UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include <iostream>
#include <fstream>
#include <string>
/*
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
*/
int main()
{
std::ifstream InFile( __FILE__ ) ;
std::string strCommand;
while ( InFile >> strCommand )
{
if (strCommand == "this-is-a-string" )
{
std::streampos nFilePosition = InFile.tellg();
std::streamoff offset = nFilePosition ;
std::cout << offset << '\n' ;
//foo(strFilename, nFilePosition);
}
InFile.ignore(1000, '\n' );
}
}
/*
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
this-is-a-string foo boo doo goo
*/
http://coliru.stacked-crooked.com/a/228a2a7adfbcfd91
Oct 23, 2013 at 6:30pm UTC
Fixed!
Thank you. The error was that Blender's text export format wasn't compatible enough with Windows' text format.
Topic archived. No new replies allowed.