Read and write image data C++ - c++

I've just started learning C++, and I'm working on a program that is supposed to grab an image from the hard disk and then save it as another name. The original image should still remain. I've got it work with text files, because with those I can just do like this:
ifstream fin("C:\\test.txt");
ofstream fout("C:\\new.txt");
char ch;
while(!fin.eof())
{
fin.get(ch);
fout.put(ch);
}
fin.close();
fout.close();
}
But I suppose that it's not like this with images. Do I have to install a lib or something like that to get it work? Or can I "just" use the included libraries? I know I'm not really an expert of C++ so please tell me if I'm totally wrong.
I hope someone can and want to help me! Thanks in advance!
Btw, the image is a .png format.

You can use the std streams but use the ios::binary argument when you open the stream. It's well documented and there is several examples around the internet

You are apparently using MS Windows: Windows distinguishes between "text" and "binary" files by different handling of line separators. For a binary file, you do not want it to translate \n\r to \n on reading. To prevent it, using the ios::binary mode when opening the file, as #Emil tells you.
BTW, you do not have to use \\ in paths under windows. Just use forward slashes:
ifstream fin("C:/test.txt");
This worked even back in WWII using MS-DOS.

If the goal is just to copy a file then CopyFile is probably better choice than doing it manually.
#include <Windows.h>
// ...
BOOL const copySuccess = CopyFile("source.png", "dest.png", failIfExists);
// TODO: handle errors.
If using Windows API is not an option, then copying a file one char at a time like you have done is very inefficient way of doing this. As others have noted, you need to open files as binary to avoid I/O messing with line endings. A simpler and more efficient way than one char at a time is this:
#include <fstream>
// ...
std::ifstream fin("source.png", std::ios::binary);
std::ofstream fout("dest.png", std::ios::binary);
// TODO: handle errors.
fout << fin.rdbuf();

Related

Cannot create a file/write to it, but can read an existing one in c++

I was just learning C++ file handling, but ran into an error immediately using this simple code to create a new file:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream file("test.txt");
file << "test";
file.close();
}
File doesn't show up. When I use .is_open(), it always gives 0. Program does compile though.
Then I manually created a .txt file with some text and tried to read it, and it worked. I supposed it was permission thingy, but it seems like all files are available to be changed? I'm not sure I completely understand how to check the permission though (I'm a bit new to all of this...), so please do help with it as well!
I use Atom and its terminal, my compiler is MingW, but I guess it might be a bit too old.
I tried to include the whole path, but it didn't work.
Thank you!
EDIT:
Just tried this code:
ofstream file;
file.open("C:\\Users\\username\\Desktop\\my_folder\\test.txt");
file << "test";
file.close();
Doesn't help. .is_open() gives 0 before I even try to write to a file.
EDIT:
Just tried this code:
fstream fileW;
fileW.open("write.txt", ios_base::in | ios_base::out | ios_base::trunc);
cout<<fileW.fail()<<endl;
cout<<fileW.is_open()<<endl;
fileW<<"Edit";
fileW.close();
Still doesn't work, returns 1 for .fail().
EDIT:
The error is "Permission denied".
EDIT:
Solved! I deleted Avast, it was blocking my program from accessing files.
Avast, I hate you. You are the worst.
Use
ofstream file("test.txt");
Your version does not create the file if it does not exist.
Similarly for input you should really use ifstream. fstream is best reserved for files you want to read and write from.

clear data inside text file in c++

I am programming on C++. In my code I create a text file, write data to the file and reading from the file using stream, after I finish the sequence I desire I wish to clear all the data inside the txt file. Can someone tell me the command to clear the data in the txt file. Thank you
If you simply open the file for writing with the truncate-option, you'll delete the content.
std::ofstream ofs;
ofs.open("test.txt", std::ofstream::out | std::ofstream::trunc);
ofs.close();
http://www.cplusplus.com/reference/fstream/ofstream/open/
As far as I am aware, simply opening the file in write mode without append mode will erase the contents of the file.
ofstream file("filename.txt"); // Without append
ofstream file("filename.txt", ios::app); // with append
The first one will place the position bit at the beginning erasing all contents while the second version will place the position bit at the end-of-file bit and write from there.
If you set the trunc flag.
#include<fstream>
using namespace std;
fstream ofs;
int main(){
ofs.open("test.txt", ios::out | ios::trunc);
ofs<<"Your content here";
ofs.close(); //Using microsoft incremental linker version 14
}
I tested this thouroughly for my own needs in a common programming situation I had. Definitely be sure to preform the ".close();" operation. If you don't do this there is no telling whether or not you you trunc or just app to the begging of the file. Depending on the file type you might just append over the file which depending on your needs may not fullfill its purpose. Be sure to call ".close();" explicity on the fstream you are trying to replace.
Deleting the file will also remove the content.
See remove file.
You should create a function which clears all the data of the file and then run it.
void clear()
{
ofstream file("fileout.txt");
file<<"";
}

How to copy files in Visual C++?

I am using Visual C++. How to copy the content of this file to another file?
UINT32 writeToLog(wstring log)
{
wfstream file1 (LOG_FILE_NAME, ios_base::out);
file1 << log;
file1.close();
// want to copy file1 to file2
return 0;
}
What exactly do you want to do? If you need a copy of the data, you can read it in and write it back out again. If you really need a copy of the file, you have to use OS specific calls.
In many cases, reading in the file data and then writing it out again to a different file is a close enough approximation to a copy - like this:
ifstream file1(...);
ofstream file2(...);
std::copy(istream_iterator<char>(file1),istream_iterator<char>(),ostream_iterator<char>(file2));
However that really isn't a copy - it's creating a new file with the same contents. It won't correctly handle hard links or symlinks, it won't correctly handle metadata and it will only 'copy' the default file stream.
If you need a file copy on Windows you should call one of CopyFile, CopyFileEx or CopyFileTransacted depending on your exact requirements.
Standard C++ has no file copying facility, other than reading the file into memory and writing it out again to a different file. As you are using Windows, you can use the CopyFile function - other OSs have similar, OS-specific functions.
The above code from Joe Gauterin did not work for me. I was trying to copy a .tga image file, so maybe something about istream_iterator<char> screwed it up. Instead I used:
ifstream file1(...);
ofstream file2(...);
char ch;
while(file1 && file1.get(ch))
{
file2.put(ch);
}

Reading bmp file for steganography

I am trying to read a bmp file in C++(Turbo). But i m not able to print binary stream.
I want to encode txt file into it and decrypt it.
How can i do this. I read that bmp file header is of 54 byte. But how and where should i append txt file in bmp file. ?
I know only Turbo C++, so it would be helpfull for me if u provide solution or suggestion related to topic for the same.
int main()
{
ifstream fr; //reads
ofstream fw; // wrrites to file
char c;
int random;
clrscr();
char file[2][100]={"s.bmp","s.txt"};
fr.open(file[0],ios::binary);//file name, mode of open, here input mode i.e. read only
if(!fr)
cout<<"File can not be opened.";
fw.open(file[1],ios::app);//file will be appended
if(!fw)
cout<<"File can not be opened";
while(!fr)
cout<<fr.get(); // error should be here. but not able to find out what error is it
fr.close();
fw.close();
getch();
}
This code is running fine when i pass txt file in binary mode
EDIT :
while(!fr)
cout<<fr.get();
I am not able to see binary data in console
this was working fine for text when i was passing character parameter in fr.get(c)
I think you question is allready answered:
Print an int in binary representation using C
convert your char to an int and you are done (at least for the output part)
With steganography, what little I know about it, you're not "appending" text. You're making subtle changes to the pixels (shading, etc..) to hide something that's not visually obvious, but should be able to be reverse-decrypted by examining the pixels. Should not have anything to do with the header.
So anyway, the point of my otherwise non-helpful answer is to encourage you go to and learn about the topic which you seek answers, so that you can design your solution, and THEN come and ask for specifics about implementation.
You need to modify the bit pattern, not append any text to the file.
One simple example :
Read the Bitmap Content (after header), and sacrifice a bit from each of the byte to hold your content
If on Windows, recode to use CreateFile and see what the real error is. If on Linux, ditto for open(2). Once you have debugged the problem you can probably shift back to iostreams.

Read Unicode files C++

I have a simple question to ask. I have a UTF 16 text file to read wich starts with FFFE. What are the C++ tools to deal with this kind of file? I just want to read it, filter some lines, and display the result.
It looks simple, but I just have experience in work with plain ascci files and I'm in the hurry. I'm using VS C++, but I'm not want to work with managed C++.
Regards
Here a put a very simple example
wifstream file;
file.open("C:\\appLog.txt", ios::in);
wchar_t buffer[2048];
file.seekg(2);
file.getline(buffer, bSize-1);
wprintf(L"%s\n", buffer);
file.close();
You can use fgetws, which reads 16-bit characters. Your file is in little-endian,byte order. Since x86 machines are also little-endian you should be able to handle the file without much trouble. When you want to do output, use fwprintf.
Also, I agree more information could be useful. For instance, you may be using a library that abstracts away some of this.
Since you are in the hurry, use ifstream in binary mode and do your job. I had the same problems with you and this saved my day. (it is not a recommended solution, of course, its just a hack)
ifstream file;
file.open("k:/test.txt", ifstream::in|ifstream::binary);
wchar_t buffer[2048];
file.seekg(2);
file.read((char*)buffer, line_length);
wprintf(L"%s\n", buffer);
file.close();
For what it's worth, I think I've read you have to use a Microsoft function which allows you to specfiy the encoding.
http://msdn.microsoft.com/en-us/library/z5hh6ee9(VS.80).aspx
The FFFE is just the initial BOM (byte order mark). Just read from the file like you normally do, but into a wide char buffer.