I have a problem with the function used to read the pgm file format to the memory .
I used the sources in the following link http://www.cse.unr.edu/~bebis/CS308/Code/ReadImage.cpp . You can find others in the same directory ; and some instructions in CS308 ; if you’re interested .
The problem is ifstream ifp fails ; and I think this piece of code maybe the reason ; but it looks fine with me .
Any ideas will be appreciated
charImage = (unsigned char *) new unsigned char [M*N];
ifp.read( reinterpret_cast<char *>(charImage), (M*N)*sizeof(unsigned char));
if (ifp.fail()) {
cout << "Image " << fname << " has wrong size" << endl;
exit(1);
}
The problem is that your input file is not formatted properly. It should have enough data to fill charImage, but it doesn't, and this is why it's failing. Another possibility is that you are trying to run this code on windows, and need to open the file in binary mode.
Specifically (for the binary part) change:
ifp.open(fname, ios::in);
to:
ifp.open(fname, ios::in | ios::binary);
As an aside, it is generally inappropriate to cast the result of a new operator. Here, it's just redundant and doesn't make any sense.
Anything using reinterpret_cast<...>() looks suspicious to me, to say the least. It is probably not the root of the problem, though. My personal guess is that the root of the problem is running the code on a Windows machine and not opening the file in binary mode. Try using
std::ifstream in("filename", std::ios_base:::binary);
Since the code opening the file isn't part of the question it is just a wild guess, though.
Related
I am trying to add some data to a specific file in my project. I am doing that in the function below.
void Files::write_employee(employee employeeObject)
{
fstream infile;
infile.open("employeeFile.txt",ios::in|ios::out|ios::app);
string record;
char delimiter='#';
record=employeeObject.get_id()+delimiter;
record+=employeeObject.get_name()+delimiter;
record+=employeeObject.get_password()+delimiter;
record+=employeeObject.get_age()+delimiter;
record+=employeeObject.get_gender()+delimiter;
record+=employeeObject.get_MaritalStatus()+delimiter;
record+=employeeObject.get_ministryName()+delimiter;
record+=employeeObject.get_departmentName()+delimiter;
record+=employeeObject.get_salary()+delimiter;
record+=employeeObject.get_photoPath()+delimiter;
record+=employeeObject.get_photoFileName()+delimiter;
if (infile.fail())exit(1);
else {infile<<record;
infile.close();}
}
This function explains how to add data to my file through save the entered data
in an object and save this values in string record and push it to the file.
The big problem is my file which I am trying to add data in, not created yet.
and I don't know why.
thanks in advance.
You use infile whereas you are outputting to file. While this does not affect the program code, it makes no sense and break your program readability. Use outfile instead.
Remember that it is just like cout << and cin >> for the standard I/O.
Also, try not to use ios::in when your purpose is only to output to the file and vise versa.
According to std::fstream::open example at cplusplus.com, your code is correct and the file must be created. First try to specify an absolute file path to a location that you have write access. If it does not work, print the error message using the following line of code:
cerr << "Error: " << strerror(errno);
TL;DR I am trying to take a stream of data and make it write to a .csv file. Everything is worked out except the writing part, which I think is simply due to me not referencing the .csv file correctly. But I'm a newbie to this stuff, and can't figure out how to correctly reference it, so I need help.
Hello, and a big thank you in advance to anyone that can help me out with this! Some advance info, my IDE is Xcode, using C++, and I'm using the Myo armband from Thalmic Labs as a device to collect data. There is a program (link for those interested enough to look at it) that is supposed to stream the EMG, accelerometer, gyroscope, and orientation values into a .csv file. I am so close to getting the app to work, but my lack of programming experience has finally caught up to me, and I am stuck on something rather simple. I know that the app can stream the data, as I have been able to make it print the EMG values in the debugging area. I can also get the app to open a .csv file, using this code:
const char *path= "/Users/username/folder/filename";
std::ofstream file(path);
std::string data("data to write to file");
file << data;
But no data ends up being streamed/printed into that file after I end the program. The only thing that I can think might be causing this is that the print function is not correctly referencing this file pathway. I would assume that to be a straightforward thing, but like I said, I am inexperienced, and do not know exactly how to address this. I am not sure what other information is necessary, so I'll just provide everything that I imagine might be helpful.
This is the function structure that is supposed to open the files: (Note: The app is intended to open the file in the same directory as itself)
void openFiles() {
time_t timestamp = std::time(0);
// Open file for EMG log
if (emgFile.is_open())
{
emgFile.close();
}
std::ostringstream emgFileString;
emgFileString << "emg-" << timestamp << ".csv";
emgFile.open(emgFileString.str(), std::ios::out);
emgFile << "timestamp,emg1,emg2,emg3,emg4,emg5,emg6,emg7,emg8" << std::endl;
This is the helper to print accelerometer and gyroscope data (There doesn't appear to be anything like this to print EMG data, but I know it does, so... Watevs):
void printVector(std::ofstream &path, uint64_t timestamp, const myo::Vector3< float > &vector)
{
path << timestamp
<< ',' << vector.x()
<< ',' << vector.y()
<< ',' << vector.z()
<< std::endl;
}
And this is the function structure that utilizes the helper:
void onAccelerometerData(myo::Myo *myo, uint64_t timestamp, const myo::Vector3< float > &accel)
{
printVector(accelerometerFile, timestamp, accel);
}
I spoke with a staff member at Thalmic Labs (the guy who made the app actually) and he said it sounded like, unless the app was just totally broken, I was potentially just having problems with the permissions on my computer. There are multiple users on this computer, so that may very well be the case, though I certainly hope not, and I'd still like to try and figure it out one more time before throwing in the towel. Again, thanks to anyone who can be of assistance! :)
My imagination is failing me. Have you tried writing to or reading from ostringstream or istringstream objects? That might be informative. Here's a line that's correct:
std::ofstream outputFile( strOutputFilename.c_str(), std::ios::app );
Note that C++ doesn't have any native support for streaming .csv code, though, you may have to do those conversions yourself. :( Things may work better if you replace the "/"'s by (doubled) "//" 's ...
Normally I live in my guarded world of C#. But sometimes I have to break out and do something outside.
At the moment I have to decode an audiostream and have to output this directly in my c++ console application.
If I write the content into a file, I can hear the correct result.
But if I use instead of a fstream cout, I get only a noisy sound.
How I have to do it correct?
Here the working filestream code:
fstream wavefile;
wavefile.open(output, ios::out | ios::binary | ios::trunc);
//do something
wavefile.write((char*) &waveheader, waveheadersize);
//do something else
do {
//do something
//decodedBuffer is of type BYTE* , decodedLength is of type DWORD
wavefile.write((char*) decodedBuffer, decodedLength);
wavefile.flush();
} while (encodedLength > 0);
My not working cout code:
std::cout.setf(ios::out | ios::binary | ios::trunc);
//do something
//this works, I got the same output
cout << structToString(&waveheader) << endl;
//do something else
do {
//do something
cout << (char *)decodedBuffer;
} while (encodedLength > 0);
Thanks in advance
First, there is absolutely no reason to use different code for a std::fstream and for std::cout (Beside which, your cout-code uses formatted output, and wrong):
You are using their ostream-interface in both cases.
So, first things first, repair the second code (as far as possible) by replacing it with the first.
Now, we come to the one difference (which you tried to paper over with setf): std::cout is in text-mode, not binary mode!
Unfortunately, none of ios::out, ios::binary and ios::trunc are formatting-flags, so you cannot set them with setf.
Actually, the mode cannot be changed at all after the fact (at least not portably).
Fortunately, you can simply ignore having the wrong mode on many systems, as Linux and others equate textmode and binary-mode. On windows, this hack should get you around it:
cout.flush();
fflush(stdout);
_setmode(_fileno(stdout), _O_BINARY);
The simple answer is that you can't. You need to output in
binary mode. The mode is selected, once and for all, when you
open the file, and std::cout is always opened in text mode.
Since you're just writing a block of bytes, the simplest
solution is to use the system level requests. Under Windows,
for example, you can use GetStdHandle( STD_OUTPUT_HANDLE ) to
get the handle to standard out, and WriteFile to write a block
of bytes to it. (Under Unix, the file descriptor for standard
out is always 1, and the function is write. But since there
is no difference between text mode and binary mode under Unix,
I assume that this isn't your case.)
Try this,
std::cout.write(reinterpret_cast<char*>(decodedBuffer), decodedLength);
But I am not sure if structToString(&waveheader) work correctly, but you seem okay with it.
I have the following code:
ofstream mOutFile.open(logPath, ios_base::app);
string lBuilder;
lBuilder.append("========================================================\n");
lBuilder.append("Date: ");
lBuilder.append(asctime(timeinfo));
lBuilder.append("\n");
lBuilder.append("Log Message:\n");
lBuilder.append(toLog);
lBuilder.append("\n");
lBuilder.append("========================================================\n\n");
int lSize = lBuilder.size();
char* lBuffer = new char[lSize];
int index = 0;
for each (char c in lBuilder)
lBuffer[index++] = c;
mOutFile.write(lBuffer, lSize);
mOutFile.flush();
Unfortunately, until I close the app (I assume that closing the ofstream would work as well) the output does not get written to the text file. I know I could probably close and reopen the stream and everything will "just work" but that seems like a silly and incorrect solution. What am I doing wrong here?
I have also tried the following variations based on other questions I have found here, but these solutions did not work:
mOutputFile << flush;
mOutputFile << endl;
Thanks in advance for any assistance on this.
edit Everything in this code is working visual c++, it builds and works fine except the file is not written to until the stream is closed, even if I force a flush. Also, I switched from using the << operator to the char * and .write () to see if anything behaved differently.
std::ofstream file(logPath, ios_base::app);
file << "========================================================\n"
<< "Date: " << asctime(timeinfo)
<< "\nLog Message:\n" << toLog
<< "\n========================================================\n\n"
<< std::flush;
//if you want to force it write to the file it will also flush when the the file object is destroyed
//file will close itself
This is not only easier to read but it will probably also be faster than your method + it is a more standard appraoch
I ended up just "making it work" by closing and reopening the stream after the write operation.
mOutputFile << "all of my text" << endl;
mOutputFile.close();
mOutputFile.open(mLogPath);
EDIT After trying out forcing the flush on a few other systems, it looks like something just isn't performing correctly on my development machine. Not good news but at least the above solution seems to work when programmatically flushing the ofstream fails. I am not sure of the implications of the above code though, so if anyone wants to chime in if there are implications of closing and reopening the stream like this.
You can perform the following steps to validate some assumptions:
1.) After flush(), the changes to the file should be visible to your application. Open the file as std::fstream instead of std::ofstream. After flushing, reset the file pointer to the beginning and read the contents of the file. Your newly written record should be there. If not, you probably have a memory corruption somewhere in your code.
2.) Open the same file in an std::ifstream after your call to flush(). Then read the contents of the file. Your newly written record should be there. If not, then there's probably another process interfering with your file.
If both works, then you may want to read up on "file locking" and "inter-process syncronization". The OS can (theoretically) take as much time as it wants to make file changes visible to other processes.
I am using the following program to try to copy the contents of a file, src, to another, dest, in C++. The simplified code is given below:
#include <fstream>
using namespace std;
int main()
{
fstream src("c:\\tplat\test\\secClassMf19.txt", fstream::binary);
ofstream dest("c:\\tplat\\test\\mf19b.txt", fstream::trunc|fstream::binary);
dest << src.rdbuf();
return 0;
}
When I built and executed the program using CODEBLOCKS ide with GCC Compiler in windows, a new file named "....mf19.txt" was created, but no data was copied into it, and filesize = 0kb. I am positive I have some data in "...secClassMf19.txt".
I experience the same problem when I compiled the same progeam in windows Visual C++ 2008.
Can anyone please help explain why I am getting this unexpected behaviour, and more importantly, how to solve the problem?
You need to check whether opening the files actually succeeds before using those streams. Also, it never hurts to check if everything went right afterwards. Change your code to this and report back:
int main()
{
std::fstream src("c:\\tplat\test\\secClassMf19.txt", std::ios::binary);
if(!src.good())
{
std::cerr << "error opening input file\n";
std::exit(1);
}
std::ofstream dest("c:\\tplat\\test\\mf19b.txt", std::ios::trunc|std::ios::binary);
if(!dest.good())
{
std::cerr << "error opening output file\n";
std::exit(2);
}
dest << src.rdbuf();
if(!src.eof())
std::cerr << "reading from file failed\n";
if(!dst.good())
std::cerr << "writing to file failed\n";
return 0;
}
I bet you will report that one of the first two checks hits.
If opening the input file fails, try opening it using std::ios::in|std::ios::binary instead of just std::ios::binary.
Do you have any reason to not use CopyFile function?
Best
As it is written, your src instance is a regular fstream, and you are not specifying an open mode for input. The simple solution is to make src an instance of ifstream, and your code works. (Just by adding one byte!)
If you had tested the input stream (as sbi suggests), you would have found that it was not opened correctly, which is why your destination file was of zero size. It was opened in write mode (since it was an ofstream) with the truncation option to make it zero, but writing the result of rdbuf() simply failed, with nothing written.
Another thing to note is that while this works fine for small files, it would be very inefficient for large files. As is, you are reading the entire contents of the source file into memory, then writing it out again in one big block. This wastes a lot of memory. You are better off reading in chunks (say 1MB for example, a reasonable size for a disk cache) and writing a chunk at a time, with the last one being the remainder of the size. To determine the source's size, you can seek to the end and query the file offset, then you know how many bytes you are processing.
And you will probably find your OS is even more efficient at copying files if you use the native APIs, but then it becomes less portable. You may want to look at the Boost filesystem module for a portable solution.