Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Black magic when using fopen!?

Reply
Thread Tools

Black magic when using fopen!?

 
 
fdm
Guest
Posts: n/a
 
      10-02-2009
In a function I call fopen:



template<class V, class Dt>
unsigned int LoadFile(std::string & path) {
std::cout << "path = " << path << std::endl;
FILE *fptr = fopen(path.c_str(), "rb");
if (fptr==NULL) {
std::cout << "file not found!" << path << std::endl;
}
...
...
}



When I run it I get this:

path = /home/fdm/test.h2
file not found!

fptr is NULL, meaning that it cannot find the file. I have double checked
that the file exist in this location.

Now here comes the wierd part. If I manually set the SAME path in the
function like:



template<class V, class Dt>
unsigned int LoadFile(std::string & path) {
std::cout << "before = " << path << std::endl;
path = "/home/fdm/test.h2";
std::cout << "after = " << path << std::endl;
FILE *fptr = fopen(path.c_str(), "rb");
if (fptr==NULL) {
std::cout << "file not found!" << path << std::endl;
}
...
...
}



I get this:

before = /home/fdm/test.h2
after = /home/fdm/test.h2

and fptr is not NULL (the file is read successfully). But as can be seen
from the printed messages there is no difference between 'path' before and
after updating it! So why does it only work when I update 'path' manually in
the function??

I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
visual studio it works fine! Any ideas??

 
Reply With Quote
 
 
 
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      10-02-2009
On Oct 2, 5:39*pm, "fdm" <(E-Mail Removed)> wrote:
> In a function I call fopen:
>
> * * template<class V, class Dt>
> * * unsigned int LoadFile(std::string & path) {
> * * * std::cout << "path = " << path << std::endl;
> * * * FILE *fptr = fopen(path.c_str(), "rb");
> * * * if (fptr==NULL) {
> * * * * std::cout << "file not found!" << path << std::endl;
> * * * }
> * * * * ...
> * * * * ...
> * * }
>
> When I run it I get this:
>
> * * *path = /home/fdm/test.h2
> * * *file not found!
>
> fptr is NULL, meaning that it cannot find the file. I have double checked
> that the file exist in this location.
>
> Now here comes the wierd part. If I manually set the SAME path in the
> function like:
>
> * * template<class V, class Dt>
> * * unsigned int LoadFile(std::string & path) {
> * * * * *std::cout << "before = " << path << std::endl;
> * * * * *path = "/home/fdm/test.h2";
> * * * * *std::cout << "after = " << path << std::endl;
> * * * * *FILE *fptr = fopen(path.c_str(), "rb");
> * * * * *if (fptr==NULL) {
> * * * * * *std::cout << "file not found!" << path << std::endl;
> * * * * *}
> * * * * *...
> * * * * *...
> * * *}
>
> I get this:
>
> * *before = /home/fdm/test.h2
> * *after = /home/fdm/test.h2
>
> and fptr is not NULL (the file is read successfully). But as can be seen
> from the printed messages there is no difference between 'path' before and
> after updating it! So why does it only work when I update 'path' manually in
> the function??
>
> I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> visual studio it works fine! Any ideas??


Perhaps there are trailing unprintable characters in the path string
passed to your function? Try printing the size of your string.

HTH
 
Reply With Quote
 
 
 
 
fdm
Guest
Posts: n/a
 
      10-02-2009

"(E-Mail Removed)" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
On Oct 2, 5:39 pm, "fdm" <(E-Mail Removed)> wrote:
> In a function I call fopen:
>
> template<class V, class Dt>
> unsigned int LoadFile(std::string & path) {
> std::cout << "path = " << path << std::endl;
> FILE *fptr = fopen(path.c_str(), "rb");
> if (fptr==NULL) {
> std::cout << "file not found!" << path << std::endl;
> }
> ...
> ...
> }
>
> When I run it I get this:
>
> path = /home/fdm/test.h2
> file not found!
>
> fptr is NULL, meaning that it cannot find the file. I have double checked
> that the file exist in this location.
>
> Now here comes the wierd part. If I manually set the SAME path in the
> function like:
>
> template<class V, class Dt>
> unsigned int LoadFile(std::string & path) {
> std::cout << "before = " << path << std::endl;
> path = "/home/fdm/test.h2";
> std::cout << "after = " << path << std::endl;
> FILE *fptr = fopen(path.c_str(), "rb");
> if (fptr==NULL) {
> std::cout << "file not found!" << path << std::endl;
> }
> ...
> ...
> }
>
> I get this:
>
> before = /home/fdm/test.h2
> after = /home/fdm/test.h2
>
> and fptr is not NULL (the file is read successfully). But as can be seen
> from the printed messages there is no difference between 'path' before and
> after updating it! So why does it only work when I update 'path' manually
> in
> the function??
>
> I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> visual studio it works fine! Any ideas??


Perhaps there are trailing unprintable characters in the path string
passed to your function? Try printing the size of your string.




Good point and you are right:


Before:

pathB size = 78


After:

pathA size = 77

But how do I find out what the last char is? There is no trim function in
the stl but I have found:

void trim2(string& str)
{
string::size_type pos = str.find_last_not_of(' ');
if(pos != string::npos) {
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos) str.erase(0, pos);
}
else str.erase(str.begin(), str.end());
}

But even if I pass my string to this function it still has size 78
afterwards! Any ideas?

 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      10-02-2009
"fdm" <(E-Mail Removed)>
> In a function I call fopen:
>
>
>
> template<class V, class Dt>
> unsigned int LoadFile(std::string & path) {
> std::cout << "path = " << path << std::endl;
> FILE *fptr = fopen(path.c_str(), "rb");
> if (fptr==NULL) {
> std::cout << "file not found!" << path << std::endl;
> }
> ...
> ...
> }
>
> When I run it I get this:
>
> path = /home/fdm/test.h2
> file not found!

....
> I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> visual studio it works fine! Any ideas??


I'd bet you have undefined behavior in your program elsewhere, so the
string's state is corrupt in the first place or the environment is. When you
call c_str() the content is gone... that is not supposed to happen.

Anyway, as first step you may try to output c_str() instead of the string,
or walk in debugger to inspect its state and what actually happens in
c_str() and what arrives to fopen().

 
Reply With Quote
 
red floyd
Guest
Posts: n/a
 
      10-03-2009
On Oct 2, 3:32*pm, "fdm" <(E-Mail Removed)> wrote:
> "(E-Mail Removed)" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed)...
> On Oct 2, 5:39 pm, "fdm" <(E-Mail Removed)> wrote:
>
>
>
> > In a function I call fopen:

>
> > template<class V, class Dt>
> > unsigned int LoadFile(std::string & path) {
> > std::cout << "path = " << path << std::endl;
> > FILE *fptr = fopen(path.c_str(), "rb");
> > if (fptr==NULL) {
> > std::cout << "file not found!" << path << std::endl;
> > }
> > ...
> > ...
> > }

>
> > When I run it I get this:

>
> > path = /home/fdm/test.h2
> > file not found!

>
> > fptr is NULL, meaning that it cannot find the file. I have double checked
> > that the file exist in this location.

>
> > Now here comes the wierd part. If I manually set the SAME path in the
> > function like:

>
> > template<class V, class Dt>
> > unsigned int LoadFile(std::string & path) {
> > std::cout << "before = " << path << std::endl;
> > path = "/home/fdm/test.h2";
> > std::cout << "after = " << path << std::endl;
> > FILE *fptr = fopen(path.c_str(), "rb");
> > if (fptr==NULL) {
> > std::cout << "file not found!" << path << std::endl;
> > }
> > ...
> > ...
> > }

>
> > I get this:

>
> > before = /home/fdm/test.h2
> > after = /home/fdm/test.h2

>
> > and fptr is not NULL (the file is read successfully). But as can be seen
> > from the printed messages there is no difference between 'path' before and
> > after updating it! So why does it only work when I update 'path' manually
> > in
> > the function??

>
> > I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> > visual studio it works fine! Any ideas??

>
> Perhaps there are trailing unprintable characters in the path string
> passed to your function? *Try printing the size of your string.
>
> Good point and you are right:
>
> Before:
>
> pathB size = 78
>
> After:
>
> pathA size = 77
>
> But how do I find out what the last char is? There is no trim function in
> the stl but I have found:

[redacted]
>
> But even if I pass my string to this function it still has size 78
> afterwards! Any ideas?


Delimiters!!!!!!

std::cout << '"' << path << '"' << std::endl;

 
Reply With Quote
 
fdm
Guest
Posts: n/a
 
      10-03-2009

"red floyd" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
On Oct 2, 3:32 pm, "fdm" <(E-Mail Removed)> wrote:
> "(E-Mail Removed)" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed)...
> On Oct 2, 5:39 pm, "fdm" <(E-Mail Removed)> wrote:
>
>
>
> > In a function I call fopen:

>
> > template<class V, class Dt>
> > unsigned int LoadFile(std::string & path) {
> > std::cout << "path = " << path << std::endl;
> > FILE *fptr = fopen(path.c_str(), "rb");
> > if (fptr==NULL) {
> > std::cout << "file not found!" << path << std::endl;
> > }
> > ...
> > ...
> > }

>
> > When I run it I get this:

>
> > path = /home/fdm/test.h2
> > file not found!

>
> > fptr is NULL, meaning that it cannot find the file. I have double
> > checked
> > that the file exist in this location.

>
> > Now here comes the wierd part. If I manually set the SAME path in the
> > function like:

>
> > template<class V, class Dt>
> > unsigned int LoadFile(std::string & path) {
> > std::cout << "before = " << path << std::endl;
> > path = "/home/fdm/test.h2";
> > std::cout << "after = " << path << std::endl;
> > FILE *fptr = fopen(path.c_str(), "rb");
> > if (fptr==NULL) {
> > std::cout << "file not found!" << path << std::endl;
> > }
> > ...
> > ...
> > }

>
> > I get this:

>
> > before = /home/fdm/test.h2
> > after = /home/fdm/test.h2

>
> > and fptr is not NULL (the file is read successfully). But as can be seen
> > from the printed messages there is no difference between 'path' before
> > and
> > after updating it! So why does it only work when I update 'path'
> > manually
> > in
> > the function??

>
> > I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> > visual studio it works fine! Any ideas??

>
> Perhaps there are trailing unprintable characters in the path string
> passed to your function? Try printing the size of your string.
>
> Good point and you are right:
>
> Before:
>
> pathB size = 78
>
> After:
>
> pathA size = 77
>
> But how do I find out what the last char is? There is no trim function in
> the stl but I have found:

[redacted]
>
> But even if I pass my string to this function it still has size 78
> afterwards! Any ideas?


Delimiters!!!!!!

std::cout << '"' << path << '"' << std::endl;




I don't understand is : -> " <- a delimiter? And I still need to make the
string identical to the manually typed string somehow.

 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      10-03-2009
On 3 Ott, 12:41, "fdm" <(E-Mail Removed)> wrote:
> "red floyd" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed)...
> On Oct 2, 3:32 pm, "fdm" <(E-Mail Removed)> wrote:
>
>
>
> > "(E-Mail Removed)" <(E-Mail Removed)> wrote in message

>
> >news:(E-Mail Removed)....
> > On Oct 2, 5:39 pm, "fdm" <(E-Mail Removed)> wrote:

>
> > > In a function I call fopen:

>
> > > template<class V, class Dt>
> > > unsigned int LoadFile(std::string & path) {
> > > std::cout << "path = " << path << std::endl;
> > > FILE *fptr = fopen(path.c_str(), "rb");
> > > if (fptr==NULL) {
> > > std::cout << "file not found!" << path << std::endl;
> > > }
> > > ...
> > > ...
> > > }

>
> > > When I run it I get this:

>
> > > path = /home/fdm/test.h2
> > > file not found!

>
> > > fptr is NULL, meaning that it cannot find the file. I have double
> > > checked
> > > that the file exist in this location.

>
> > > Now here comes the wierd part. If I manually set the SAME path in the
> > > function like:

>
> > > template<class V, class Dt>
> > > unsigned int LoadFile(std::string & path) {
> > > std::cout << "before = " << path << std::endl;
> > > path = "/home/fdm/test.h2";
> > > std::cout << "after = " << path << std::endl;
> > > FILE *fptr = fopen(path.c_str(), "rb");
> > > if (fptr==NULL) {
> > > std::cout << "file not found!" << path << std::endl;
> > > }
> > > ...
> > > ...
> > > }

>
> > > I get this:

>
> > > before = /home/fdm/test.h2
> > > after = /home/fdm/test.h2

>
> > > and fptr is not NULL (the file is read successfully). But as can be seen
> > > from the printed messages there is no difference between 'path' before
> > > and
> > > after updating it! So why does it only work when I update 'path'
> > > manually
> > > in
> > > the function??

>
> > > I get this error on Ubuntu 9.04. If I run it on windows vista 64 bit in
> > > visual studio it works fine! Any ideas??

>
> > Perhaps there are trailing unprintable characters in the path string
> > passed to your function? Try printing the size of your string.

>
> > Good point and you are right:

>
> > Before:

>
> > pathB size = 78

>
> > After:

>
> > pathA size = 77

>
> > But how do I find out what the last char is? There is no trim function in
> > the stl but I have found:

> [redacted]
>
> > But even if I pass my string to this function it still has size 78
> > afterwards! Any ideas?

>
> Delimiters!!!!!!
>
> std::cout << '"' << path << '"' << std::endl;
>
> I don't understand is : -> *" *<- a delimiter?


Yes, it is.

std::cout << "[" << path << "]" << std::endl;

is fine too, the point is checking if you're getting what you're
expecting or not.

This output is fine:

[folder/filename.ext]

these are not:

[folder/filename.ext ] <- probably a trailing tab character

[folder/filename.ext
] <- probably a new-line and/or a carriage-return trailing character

> And I still need to make the
> string identical to the manually typed string somehow.


The target is that, but the questions to answer should be: "Why am I
_not_ getting what I expect? Which part of the program is messing up
the 'path' string?"

By the way, your quoting is messed up. Fix it for the future.

Also, why are you using fopen and not filestreams? Just out of
curiosity.

--
Francesco S. Carta, hobbyist
http://fscode.altervista.org
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      10-03-2009
On 3 Ott, 13:52, "Francesco S. Carta" <(E-Mail Removed)> wrote:
> On 3 Ott, 12:41, "fdm" <(E-Mail Removed)> wrote:


[snip]

> > I don't understand is : -> *" *<- a delimiter?

>
> Yes, it is.
>
> std::cout << "[" << path << "]" << std::endl;
>
> is fine too, the point is checking if you're getting what you're
> expecting or not.
>
> This output is fine:
>
> [folder/filename.ext]
>
> these are not:
>
> [folder/filename.ext * *] <- probably a trailing tab character
>
> [folder/filename.ext
> ] <- probably a new-line and/or a carriage-return trailing character
>
> > * * * * * * * * * * * * And I still need to make the
> > string identical to the manually typed string somehow.

>
> The target is that, but the questions to answer should be: "Why am I
> _not_ getting what I expect? Which part of the program is messing up
> the 'path' string?"


Consider also that you might be having a messed up 'path' string from
starters.
How are you filling it in first place?

--
Francesco S. Carta, hobbyist
http://fscode.altervista.org
 
Reply With Quote
 
LR
Guest
Posts: n/a
 
      10-03-2009
red floyd wrote:
> On Oct 2, 3:32 pm, "fdm" <(E-Mail Removed)> wrote:
>> "(E-Mail Removed)" <(E-Mail Removed)> wrote in message


>> But how do I find out what the last char is? There is no trim function in
>> the stl but I have found:

> [redacted]
>> But even if I pass my string to this function it still has size 78
>> afterwards! Any ideas?

>
> Delimiters!!!!!!
>
> std::cout << '"' << path << '"' << std::endl;


I think that delimiters can be useful, but are sometimes misleading.
Better to dump the string as octal, hex or decimal and see what's in it.

This code may be useful as a point of departure. Please watch for any
portability issues I missed.

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <limits.h>

std::string dump(const std::string &s) {
std::stringstream o;
o << (unsigned long int)(s.size()) << std::endl;
o << "*" << s << "*" << std::endl;

// if the number of bits in char
// isn't a multiple of 4, fix this
static const size_t hexWidth = CHAR_BIT/4;
for(std::string::const_iterator i=s.begin(); i!=s.end(); i++) {
o
<< std::hex
<< std::setfill('0')
<< std::setw(hexWidth)
<< int(*i)
<< " "
<< std::dec; // not the best place for this
}
return o.str();
}

int main() {
const std::string backspace(1,; // YMMV, this is for ascii
const std::string nullchar(1,0);
const std::string hw("hello world");
const std::string ick = hw + nullchar + backspace;

std::cout << "hw\n" << dump(hw) << std::endl;
std::cout << "ick\n" << dump(ick) << std::endl;
}
On my computer the output was:
hw
11
*hello world*
68 65 6c 6c 6f 20 77 6f 72 6c 64
ick
13
*hello world*
68 65 6c 6c 6f 20 77 6f 72 6c 64 00 08

LR


 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      10-03-2009
"(E-Mail Removed)" wrote:
> Perhaps there are trailing unprintable characters in the path string
> passed to your function? Try printing the size of your string.


fdm wrote:
> Good point and you are right:
>
>
> Before:
>
> pathB size = 78
>
>
> After:
>
> pathA size = 77
>
> But how do I find out what the last char is? There is no trim function
> in the stl but I have found:
>
> void trim2(string& str)
> {
> string::size_type pos = str.find_last_not_of(' ');
> if(pos != string::npos) {
> str.erase(pos + 1);
> pos = str.find_first_not_of(' ');
> if(pos != string::npos) str.erase(0, pos);
> }
> else str.erase(str.begin(), str.end());
> }
>
> But even if I pass my string to this function it still has size 78
> afterwards! Any ideas?


That depends on how do you construct your string. Show us that code.

But I guess that you put a C-style string into that std::string, and
those are delimited by a final '\0' character. The standard way to get
its size is by strlen. You can resize your string using the resize
member function to this size:

void trim_cstring(string& str)
{
str.resize( strlen(&str[0]) );
}

By the way, it is good style to pass variables you don't want to change
in a function by const reference:

unsigned int LoadFile(std::string const& path);

This way, the user of this function knows that you don't change the
string and can rely on it. Additionally, you can pass a temporary string
to the function which you can't if the parameter is a non-const reference.

--
Thomas
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
magic / counter-magic? (detect loading file?) Giles Bowkett Ruby 9 12-17-2007 05:42 AM
Black Magic - Currying using __get__ Michael Spencer Python 0 03-24-2005 07:27 PM
Deep Black Magic in Python: please help Jan Burgy Python 2 08-16-2004 07:04 AM



Advertisments