QString to char not working - c++

I try the following where I added date and time but now nothing is written to the file. ??
QString hoho = QDate::currentDate().toString("yyyy.MM.dd") + QTime::currentTime().toString(".hh.mm.ss.zzz");
fprintf(fp, "%s timer timer3 timer5 timer6 timer7\n", hoho.toStdString().c_str());

A FILE* is normally fully buffered, meaning nothing is written to the file until the internal buffer of the FILE* is full, or until you flush the FILE* (flushing is also done when closing the file).
So flush it by adding this after the fprintf() call:
fflush(fp);

Related

Reading a file and saving the same exact file c++

I am actually writing a c++ program that reads any kind of file and saves it as a bmp file, but first I need to read the file, and thats were the issue is
char fileName[] = "test.jpg";
FILE * inFileForGettingSize;//This is for getting the file size
fopen_s(&inFileForGettingSize, fileName, "r");
fseek(inFileForGettingSize, 0L, SEEK_END);
int fileSize = ftell(inFileForGettingSize);
fclose(inFileForGettingSize);
ifstream inFile;//This is for reading the file
inFile.open(fileName);
if (inFile.fail()) {
cerr << "Error Opening File" << endl;
}
char * data = new char[fileSize];
inFile.read(data, fileSize);
ofstream outFile;//Writing the file back again
outFile.open("out.jpg");
outFile.write(data, fileSize);
outFile.close();
cin.get();
But when I read the file, lets say its a plainttext file it allways outputs some wierd charactes at the end, for example:
assdassaasd
sdaasddsa
sdadsa
passes to:
assdassaasd
sdaasddsa
sdadsaÍÍÍ
So when I do this with a jpg, exe, etc. It corrupts it.
I am not trying to COPY a file, I know there are other ways for that, Im just trying to read a complete file byte per byte. Thanks.
EDIT:
I found out that those 'Í' are equal to the number of end lines the file has, but this doesn't help me much
This is caused by newline handling.
You open the files in text mode (because you use "r" instead of "rb" for fopen and because you don't pass ios::binary to your fstream open calls), and on Windows, text mode translates "\r\n" pairs to "\n" on reading and back to "\r\n" when writing. The result is that the in-memory size is going to be shorter than the on-disk size, so when you try to write using the on-disk size, you go past the end of your array and write whatever random stuff happens to reside in memory.
You need to open files in binary mode when working with binary data:
fopen_s(&inFileForGettingSize, fileName, "rb");
inFile.open(fileName, ios::binary);
outFile.open("out.jpg", ios::binary);
For future reference, your copy routine could be improved. Mixing FILE* I/O with iostream I/O feels awkward, and opening and closing the file twice is extra work, and (most importantly), if your routine is ever run on a large enough file, it will exhaust memory trying to load the entire file into RAM. Copying a block at a time would be better:
const int BUFFER_SIZE = 65536;
char buffer[BUFFER_SIZE];
while (source.good()) {
source.read(buffer, BUFFER_SIZE);
dest.write(buffer, source.gcount());
}
It's a binary file, so you need to read and write the file as binary; otherwise it's treated as text, and assumed to have newlines that need translation.
In your call to fopen(), you need add the "b" designator:
fopen_s(&inFileForGettingSize, fileName, "rb");
And in your fstream::open calls, you need to add std::fstream::binary:
inFile.open(fileName, std::fstream::binary);
// ...
outFile.open("out.jpg", std::fstream::binary);

overwrite file (not append) in c++

I need to modify code written in c++. The code opens a file authfile and writes 49 bytes to it. In case the file already exists, I need to make sure the existing data will be overwritten.
The original code first deleted the file and then created a new file. For reasons beyond this discussion, I cannot delete the file, I only need to make sure it is empty, before i write new data to it.
Below is the function that writes the data. How can I modify it, so thatexisting content of the file will be overwritten ?
I suppose, I need to tchange the options of popen
bool Util::add_mcookie(const std::string &mcookie, const char *display,
const std::string &xauth_cmd, const std::string &authfile)
{
FILE *fp;
std::string cmd = xauth_cmd + " -f " + authfile + " -q";
fp = popen(cmd.c_str(), "w");
if (!fp)
return false;
fprintf(fp, "remove %s\n", display);
fprintf(fp, "add %s %s %s\n", display, ".", mcookie.c_str());
fprintf(fp, "exit\n");
pclose(fp);
return true;
}
Change popen to fopen and pclose to fclose. popen / pclose is for opening / closing a process. Also, it looks like you're creating the process with flags. You just need to give fopen the file path

Append Packet to Current PCAP file

I wrote the following code to capture packets; but, it actually save the last packet.
process_Packet(const struct pcap_pkthdr *header,
const u_char * packet)
{
FILE* pFile = NULL;
pFile = fopen ("myfile.pcap" , "wb"); // open for writing in binary mode
pcap_dumper_t * dumpfile = pcap_dump_fopen(pcap_handle,pFile);
if (dumpfile == NULL)
{
printf("***NOOOO Dump!!!!!!!***");
}
else
{
pcap_dump((unsigned char *) dumpfile, header, packet);
printf("***Dumped!!!!!!!***");
}
pcap_dump_close(dumpfile);
}
I want to write a code that collect packets and append the new packet to previous ones.
I should say that fopen("...", "ab") corrupts the file and doesn't work.
pcap_dump_fopen writes some initialization headers, so it should be called only once on empty file. After file with headers created you actually can pass FILE* instance opened in append mode to pcap_dump directly casted to unsigned char *. But it is not safe approach - better at least write all required fields yourself (it's like 10 lines anyway) since function implementation may change in the future and file format will not. And I don't really understand why you would like to reopen file on every packet dumped. If you want to ensure all data is written you can just call fflush.

ifstream.eof() - end of file is reached before the real end

I have a roughly 11.1G binary file where stores a series of the depth frames from the Kinect. There are 19437 frames in this file. To read one frame per time, I use ifstream in fstream but it reaches eof before the real end of the file. (I only got the first 20 frames, and the function stops because of the eof flag)
However, all frames can be read by using fread in stdio instead.
Can anyone explain this situation? Thank you for precious time on my question.
Here are my two functions:
// ifstream.read() - Does Not Work: the loop will stop after 20th frame because of the eof flag
ifstream depthStream("fileName.dat");
if(depthStream.is_open())
{
while(!depthStream.eof())
{
char* buffer = new char[640*480*2];
depthStream.read(buffer, 640*480*2);
// Store the buffer data in OpenCV Mat
delete[] buffer;
}
}
// fread() - Work: Get 19437 frames successfully
FILE* depthStream
depthStream = fopen("fileName.dat", "rb");
if(depthStream != NULL)
{
while(!feof(depthStream))
{
char* buffer = new char[640*480*2];
fread(buffer, 1, 640*480*2, depthStream);
// Store the buffer data in OpenCV Mat
delete[] buffer;
}
Again, thank you for precious time on my question
You need to open the stream in binary mode, otherwise it will stop at the first byte it sees with a value of 26.
ifstream depthStream("fileName.dat", ios_base::in | ios_base::binary);
As for why 26 is special, it's the code for Ctrl-Z which was a convention used to mark the end of a text file. The history behind this was recorded in Raymond Chen's blog.

Finding and replacing string tokens in a file in C++ using win32 API

I'm trying to find a way to replace all instances of a string token in a file with another string.
How can I do this in C++ with the win32 API?
In other languages this is an easy thing to do, but in C++ I am just lost.
EDIT: For some context, this is for a WiX custom action. So portability is not a main priority, just the most simplest solution.
If the file fits in memory – it's simpler. Call OpenFile() to open file, GetFileSize() to determine file size, allocate enough memory, call ReadFile() to read file, then CloseFile. Do replacement in memory (use strstr() or similar function), then again OpenFile(), WriteFile(), CloseFile().
If the file is large - create a temporary file and read the source file in chunks and write filtered text to the temporary file, then call DeleteFile() to delete the original file and MoveFile() to move the filtered file.
You could use the Boost.Regex Library which should resemble most of the functionality you find on other platforms.
It would work like this:
In this example you’ll find how you can replace a string matching a pattern.
#include <boost/regex.hpp>
#include <string>
int main()
{
boost::regex pattern ("b.lug",boost::regex_constants::icase|boost::regex_constants::perl);
std::string stringa ("Searching for bolug");
std::string replace ("BgLug");
std::string newString;
newString = boost::regex_replace (stringa, pattern, replace);
printf("The new string is: |%s|\n",newString.c_str());
return 0;
}
but you would have of course to add the file reading/writing.
As per sharptooth's solution, I knocked up some C code to do a find and replace on a file. I used stdio calls (strlen, strstr, strcpy and strcat) to do the string manipulation (rather than win32 calls), so your only dependancy is the C run time.
This is certainly not code I would use in a production system. I would use stuff from toolkit string manipulation libraries to make this much cleaner (and not so much with the fixed length buffers). I probably wouldn't use boost, I don't like the overhead. But I figured you might like an example with just the basics (N.B. This writes the altered buffers out to .temp).
#include <stdio.h>
#define BUF_LEN 2048
int findAndReplace (const char * file, const char * find, const char * replace)
{
int replaceCount = 0;
FILE * f = fopen (file, "rt");
if (strstr(replace, find))
return 0; // replacing blah with stuff_blah_stuff
unsigned int findLen = strlen (find);
char tempFile [BUF_LEN];
strcpy (tempFile, file);
strcat (tempFile, ".temp");
FILE * writeF = fopen (tempFile, "wt");
if (!f || !writeF)
return 0;
printf ("Processing %s - %s to %s\n", file, find, replace);
char lineBuf [BUF_LEN];
memset (lineBuf, 0, BUF_LEN);
char tempLineBuf [BUF_LEN];
memset (tempLineBuf, 0, BUF_LEN);
// read each line of the file
while (fgets (lineBuf, BUF_LEN, f))
{
// get the position of find in the line buffer
char * pos = strstr (lineBuf, find);
while (pos)
{
strncpy (tempLineBuf, lineBuf, pos - lineBuf);
strcat (tempLineBuf, replace);
strcat (tempLineBuf, pos + findLen);
replaceCount++;
// replace the current buf with the replaced buffer
strncpy (lineBuf, tempLineBuf, BUF_LEN);
memset (tempLineBuf, 0, BUF_LEN);
pos = strstr (lineBuf, find);
}
printf ("writing new line %s\n", lineBuf);
fputs (lineBuf, writeF);
}
fclose (f);
fclose (writeF);
return replaceCount;
}
int main ()
{
printf ("Made %d replacements\n", findAndReplace ("blah.txt", "marker", "testing_blah"));
}
Why do you have to use the Win32 API? It's easy enough using straight C++, I wouldn't confuse the issue by adding artificial constraints. Just open your input file, open an output file, and read a line from your input. While you haven't hit EOF in your input file, use a regex to look for your token. If you find it, then replace it with your text. Write the line to the output file. Read another line from the input. When you get EOF on the input, close it. Be sure any pending output gets flushed from the output buffer. Close the output file. Done.