View Full Version : ofstream (standard C++ file output) not working
byteit101
01-01-2010, 12:08
I was testing a logging system, where you would be able to log data to a logfile on the cRIO, and then FTP to it to see what happened. I used a modified simpleRobot, and added a streambuf* to the variable list, a ofstream, initialized to "cRIOUserLog.log", and then rdbuf to clog. but clog<<"Logging Test"<<endl; (which should also flush) does not appear to do anything. I FTP'd to the cRIO, and looked in most of the directories, but I cannot find cRIOUserLog.log. Is there something I need to do? I remember someone somewhere in some thread somewhile ago saying something about a write flag, but I was able to use IMAQ_write_png (don't think this is the actual name) to write PNG's to the cRIO.
Relevant code:
class SuperSimpleRobot
{
streambuf* ofsTclog;
ofstream UserLog;
//...
public:
SuperSimpleRobot():
UserLog("cRIOUserLog.log")//...
{
ofsTclog=UserLog.rdbuf();
clog.rdbuf(ofTclog);
//...
clog<<"Logging Test"<<endl;
}
//...
};
Pat Fairbank
01-01-2010, 12:55
Try calling Priv_SetWriteFileAllowed(1) in the constructor.
I've never used ofstream on the cRIO, but I've gotten C-style file I/O to work (FILE*, fopen(), fwrite(), etc.).
slavik262
01-01-2010, 17:38
Ditto. C-style has always run fine with me. If you know what you're doing it's not that hard to make a class similar to ofstream with c-style calls.
byteit101
01-01-2010, 18:26
Try calling Priv_SetWriteFileAllowed(1) in the constructor.
I've never used ofstream on the cRIO, but I've gotten C-style file I/O to work (FILE*, fopen(), fwrite(), etc.).
Thanks! I will try that next time I get a chance.
Ditto. C-style has always run fine with me. If you know what you're doing it's not that hard to make a class similar to ofstream with c-style calls.
I know about C IO, but like C++ much better due to its simplicity, and ease of use by semi-incompetent people
slavik262
02-01-2010, 11:40
What I was saying is that if you can't get ofstream to work, write your own class that copies its behavior and use the C-style I/O in the member functions.
byteit101
02-01-2010, 12:37
What I was saying is that if you can't get ofstream to work, write your own class that copies its behavior and use the C-style I/O in the member functions.
if C style works, why would ofstream not work?
Jared Russell
02-01-2010, 18:01
The cRIO requires that you call Priv_SetWriteFileAllowed(1) before you can create files on the cRIO file system. You seem to be instantiating your ofstream object in the initialization list of your main robot class; in this case, the ofstream would attempt to create the specified file BEFORE you have allowed such an activity to take place (even if you call Priv_SetWriteFileAllowed(1) in your robot class's constructor - the initialization list gets executed first).
Also, ofstream has several methods that can be useful in diagnosing what has gone wrong. In particular, look at is_open(), good(), fail(), bad(), rdstate() here: http://www.cplusplus.com/reference/iostream/ofstream/
Hope this helps!
byteit101
02-01-2010, 20:16
any files?
when we saved camera png's we did not have to call Priv_SetWriteFileAllowed(1)
slavik262
04-01-2010, 07:39
if C style works, why would ofstream not work?
It's a great question, but I've never had any issues reading/writing to the robot using C file I/O, and I've never called Priv_SetWriteFileAllowed(1). I know my suggestion is more of a workaround than a real answer, but I just thought it might help.
karatekid
10-01-2010, 19:47
I got this from cprogramming.com:
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char str[10];
//Creates an instance of ofstream, and opens example.txt
ofstream a_file ( "example.txt" );
// Outputs to example.txt through a_file
a_file<<"This text will now be inside of example.txt";
// Close the file stream explicitly
a_file.close();
//Opens for reading the file
ifstream b_file ( "example.txt" );
//Reads one string from the file
b_file>> str;
//Should output 'this'
cout<< str <<"\n";
// b_file is closed implicitly here
}
This is how it is done in c++, for both input and output-this may not help, because I do not know how it will work with the robot, put it works for regular programs. Also, this only works for text files to my knowledge...
byteit101
11-01-2010, 15:24
karatekid, I don't think you know what this thread is about. I know how to use o/i/fstream, but cannot find the file it (supposedly)creates. This format (should) work for the robot, as well as any other target supporting C++ io. And it works for binary fills also
Another thought: would I have to use /myfile instead of just myfile?
karatekid
11-01-2010, 20:21
Sorry?
slavik262
13-01-2010, 11:03
Any luck so far or is it still not working?
Also, I don't remember needing a forward slash in front of the filename when saving.
Jared Russell
13-01-2010, 11:28
In Java, I recall I had to use a "file://" prefix on my filename (for example: "file://mylog.txt") in order to get file creation to work. Perhaps you have to do the same thing here?
byteit101
13-01-2010, 16:49
Haven't tried to do it yet, yesterday we we only able to get LV/WR/NB installed. I think I might be able to test it Thursday, but definitely by Saturday.
Interesting Jared341, I will try this.
davidalln
19-01-2010, 18:11
Did you or anyone else successfully get a log running on their cRio? We are trying to do something similar, and we have had consistent success with creating the file but very spotty success when writing to it (depending on where the lines are added in the code). Sometimes it works sometimes it doesn't.
slavik262
25-01-2010, 14:37
I know this is quite a bump, but now I'm even having problems using C file I/O with FILE* pointers. I've called Priv_SetWriteAllowed(1) and still weird stuff happens. Sometimes things work fine, but there's a boat load of issues most of the time:
While some files write fine, others don't write at all, and still others write nothing but whitespace.
fwrite() reformats strings for some bizarre reason. Example: I wanted to print some formatted data into a .csv (comma seperated value) file. I used sprintf() to print some floats with some commas, carraige returns, and line feeds. Calling printf() on the string created with sprintf() yields what I would expect, but when I write the exact same string to the file with fwrite(), every float is smaller by two orders of magnitude.
Does anybody have any idea what could be causing this? It's making things very difficult and I can't imagine why it would be happening.
TheDominis
25-01-2010, 22:16
I've found that some parts of the STL do not work with well/at all Wind River. I tried to use std::fstream to store some packet data, but had to use c-style file I/O for it to work.
slavik262
26-01-2010, 00:15
I've found that some parts of the STL do not work with well/at all Wind River. I tried to use std::fstream to store some packet data, but had to use c-style file I/O for it to work.
C-style file I/O isn't working for me at all either... :confused:
TheDominis
26-01-2010, 13:35
C-style file I/O isn't working for me at all either... :confused:
Interesting. What permissions are you using? I used "w".
slavik262
26-01-2010, 16:37
I was using w. I guess I could try wb or w+, but I was just writing text...
byteit101
31-01-2010, 19:57
I (finally!) got a chance to test this again.
code (in auto)
ofstream txt;
txt.open("test.txt");
txt<<"IT WORKS!!!"<<endl;
for some reason, (without the priv_setwrite stuff) it worked 2 of the three times i tested it. No difference except different flies
slavik262
01-02-2010, 10:04
Exactly! That's what's so odd about it. It's not even that it doesn't work, but that it works inconsistantly with no changes except filenames. I have no idea what could be causing the problem. It's so frustrating. :mad:
On the note of standard library things failing, does anyone have issues with std::cout? printf() works fine, but cout refuses to print a thing. I'm using the VxWorks Target Console in WindRiver.
byteit101
01-02-2010, 15:10
Exactly! That's what's so odd about it. It's not even that it doesn't work, but that it works inconsistantly with no changes except filenames. I have no idea what could be causing the problem. It's so frustrating. :mad:
On the note of standard library things failing, does anyone have issues with std::cout? printf() works fine, but cout refuses to print a thing. I'm using the VxWorks Target Console in WindRiver.
cout is mis-directed most of the time (strange), but cerr is working fine for us. we rdbuf it though,
streambuf *cerbuf=cerr.rdbuf();
cout.rdbuf(cerbuf);
EDIT: now that I think about it, the getting started guided called it printf/cout output. strange they did not get it working with that title
On the note of standard library things failing, does anyone have issues with std::cout? printf() works fine, but cout refuses to print a thing. I'm using the VxWorks Target Console in WindRiver.
This is a known issue with the Target Console. cout does not work, but printf does. If you are using the Serial console, I believe the cout will work. Probably with NetConsole as well, but I haven't tried it. I tend to completely avoid things that work "in certain cases".
It never bothered me, though since I like to format the things I print and inserting magic format objects feels like a lame hack compared to a concise format string. Oh well... preferences, I guess.
-Joe
...for some reason, (without the priv_setwrite stuff) it worked 2 of the three times i tested it. No difference except different flies
This sounds like a race condition to me. I know there are several files in the vision code (and probably others) that call Priv_SetWriteFileAllowed in some cases. Perhaps in the test runs where it works, that code happened to win the race against your test code.
-Joe
slavik262
03-02-2010, 08:37
I agree that behavior like this sounds like a race condition, but why would a race occur for a file stream, especially to a file that's not used by any other part of the system?
I agree that behavior like this sounds like a race condition, but why would a race occur for a file stream, especially to a file that's not used by any other part of the system?
I was under the impression that Priv_SetWriteFileAllowed was a global system setting, not associated with any particular task or file handle. If the fopen is racing with Priv_SetWriteFileAllowed, it doesn't matter who is calling each of them.
-Joe
slavik262
03-02-2010, 18:06
I was under the impression that Priv_SetWriteFileAllowed was a global system setting, not associated with any particular task or file handle. If the fopen is racing with Priv_SetWriteFileAllowed, it doesn't matter who is calling each of them.
-Joe
From my understanding, you call Priv_SetWriteFileAllowed(1) to allow a file write operation and then call fopen() as usual.
From my understanding, you call Priv_SetWriteFileAllowed(1) to allow a file write operation and then call fopen() as usual.
Yes... and...
The way I understand it, it enables write access to the filesystem as a whole. In other words, if no one calls it, noone can write to the disk. If anyone calls it, then anyone can write to the disk (or open for write).
slavik262
04-02-2010, 10:54
Right, so if it is called before fopen() in the same thread, why would there be a race condition?
I think we're having some kind of communication disconnect. Sorry.
Right, so if it is called before fopen() in the same thread, why would there be a race condition?
You would not. The situation described above (or how I read it anyway) was that you were not calling Priv_SetWriteFileAllowed, and that it sometimes worked. I was suggesting that there are other tasks that may be calling it that would allow the write to work sometimes and not others.
If what you are saying is that you are calling it in the same task before the fopen and it still only works some of the time, then I don't have a good theory for you. Let me know if this is the case and I'll try to look into it a bit more.
-Joe
byteit101
04-02-2010, 15:20
A race condition would make sense, originally, I had the write in the simple template constructor, later i put it in the auto. I will test out the race condition today. My plan:
write to file in entry point function before anything else
write to file in robot constructor
write to file in robot auto after 10 second wait
they will be tested 10 times without priv_set..., and 10 times with priv_set...
I will report back later
byteit101
04-02-2010, 19:09
Hmm, I am not seeing any blocked attempts to write; Every test was successful, without the priv_set... Sometimes it took up to 10 seconds to find it over FTP, but every test was successful
Sometimes it took up to 10 seconds to find it over FTP, but every test was successful
Make sure your FTP client is not caching the directory listing. What client are you using?
byteit101
05-02-2010, 06:29
Make sure your FTP client is not caching the directory listing. What client are you using?
FileZilla
FileZilla
Hmm... should be fine as long as you refresh and are connected. Have you tried putting prints to go along with your writes to get some idea of when the write happened vs. when you see the file on the FTP server?
byteit101
05-02-2010, 15:49
no, but I think it might be the code is slow (I only immediatly looked at the folder for a few test), you hit Run kernel task and it downloads, (I was measuring from that point), it calls the entry point function, and inits everything before creating the file
davidalln
05-02-2010, 18:27
We finally got our log working consistently (although not as sophisticated as 3132's Logger (http://www.chiefdelphi.com/forums/showthread.php?t=81937), it's a foundation in which stuff can be added on). It looks like the race condition problems listed above were the culprit. The key is not to completely overwhelm it with added lines in the main loop.
We have wrapped it in a class if anyone's interested: http://gist.github.com/296373
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.