I composed below code to readback binary files by VC2017. In debug mode, I like to see the values in "buffer". but I could not see readable values.
my questions are:
how can I view the readable result?
I did "sizeof(buffer)", it returned 4, which was less than what I expected. I expected the buffer to be same size and the file size. why?
Thank you very much for enlightening me.
char* read_back(const char* filename)
{
FILE* pFile;
long lSize;
char* buffer;
pFile = fopen(filename, "rb");
if (pFile == NULL)
{
fputs("File error", stderr);
exit(1);
}
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile); // set file pos at the begining
// copy the file into the buffer:
buffer = (char*)malloc(sizeof(char)*lSize);
size_t result = fread(buffer, 1, lSize, pFile);
if (result != lSize)
{
fputs("Reading error", stderr);
exit(3);
}
fclose(pFile);
return buffer;
}
Here's how to do your code in C++ (not the C code that you actually have)
#include <fstream>
#include <sstream>
#include <string>
std::string read_back(const char* filename)
{
std::ifstream file(filename, std::ios_base::binary);
std::ostringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
It returns a std::string not a char* but that's a good thing, because you don't have the issue of remembering to have to free the allocated memory.
As has been explained you misunderstand how pointers and sizeof work. Avoid pointers, they're hard.
Related
the program is to read back multiple bin files
there is an above-mentioned error happened at the end of "main" program. where did I code wrong? thank you for help
char* read_back(const char* filename)
{
FILE* pFile;
long lSize;
char* buffer;
pFile = fopen(filename, "rb");
if (pFile == NULL) { fputs("File error", stderr); exit(1); }
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile); // set file pos at the begining
// copy the file into the buffer:
buffer = (char*)malloc(sizeof(char)*lSize);
size_t result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { fputs("Reading error", stderr); exit(3); }
fclose(pFile);
return buffer;
}
int main() {
const char *fname[2] ;
fname[0] = "C:\\0_data.bin";
fname[1] = "C:\\1_data.bin";
fname[2] = "C:\\2_data.bin";
int i;
char * readback_data;
for (i = 0; i < 3; ++i)
{
readback_data=read_back(fname[i]);
}
return 0;
}
const char *fname[2] ;
This declares an array with two values, two pointers: fname[0] and fname[1].
fname[0] = "C:\\0_data.bin";
fname[1] = "C:\\1_data.bin";
fname[2] = "C:\\2_data.bin";
This attempts to put three pointers into an array that's sized only for two. That's your stack corruption, right here.
I have a simple implementation of AES (CTR Mode, which allows encrypting/decrypting more than 16bytes)
And I want to read a file to a char array and then to encrypt it.
I have tried the following, without success:
long GetFileSize(const char* filePath)
{
FILE* pFile = fopen(filePath, "rb");
if (pFile == NULL)
{
printf("error");
getchar();
}
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);
fclose(pFile);
return lSize;
}
// Reads given file to buffer, and returns pointer to that buffer.
// Caller should free this memory later.
unsigned char * ReadFile(const char * filePath)
{
FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;
pFile = fopen(filePath, "rb");
if (pFile == NULL) { fputs("File error", stderr); ; }
// obtain file size:
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
// allocate memory to contain the whole file:
buffer = (unsigned char*)malloc(sizeof(unsigned char)*lSize);
if (buffer == NULL) { fputs("Memory error", stderr); ; }
// copy the file into the buffer:
result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { fputs("Reading error", stderr); ; }
// terminate
fclose(pFile);
// the whole file is now loaded in the memory buffer. Return pointer to data.
return buffer;
}
int main(int argc, char *argv[])
{
//All char arrays are null terminated here...
uchar szkey[KEY_128] = "very strong key";
const char *filePath = "key.txt";
// Get file size which must be encrypted
long originalSize = GetFileSize(filePath);
// Make this size multiple of block size (16 bytes).
long multipleSize = (originalSize / 16 + 1) * 16;
// Store number of bytes that were needed for padding.
int nrOfPaddingBytes = (int)(multipleSize - originalSize);
// Now, read the file.
unsigned char * fileContents = ReadFile(filePath);
// Create a large buffer to store file contents (including padding bytes),
// and copy file contents to it.
unsigned char * buffer = (unsigned char*)malloc(multipleSize);
memcpy(buffer, fileContents, originalSize);
// Allocate space for ciphertext also (should also have size multiple of 8).
unsigned char * ciphertext = (unsigned char*)malloc(multipleSize);
char* cipherhex = (char*)malloc(multipleSize * 2);
char* decryptedhex = (char*)malloc(multipleSize);
unsigned char* dechex = (unsigned char*)malloc(multipleSize);
// Delete old file buffer.
free(fileContents);
fileContents = NULL;
// Pad the plaintext
for (int i = 0; i < nrOfPaddingBytes; i++)
{
buffer[originalSize + i] = nrOfPaddingBytes;
}
aes_ctx_t *ctx;
u64 nonce;
virtualAES::initialize();
ctx = virtualAES::allocatectx(szkey, sizeof(szkey));
virtualAES::rand_nonce(&nonce);
//encrypt
virtualAES::encrypt_ctr(ctx, buffer, ciphertext, sizeof(buffer), nonce);
cout << "cipherdata in ansi:\n" << ciphertext << "\n\n";
virtualAES::strtohex(ciphertext, cipherhex, originalSize);
cout << "cipherdata in hex:\n" << cipherhex << "\n\n";
return 0;
}
but it fails for some reason. Could someone provide me an algorithm to read a file for encrypting?
I am reading a raw file which is having only 1's and 0's which i have saved from SurfaceFlinger into a character buffer and write to IplImage. Then I am trying to write it to a video file but cvWriteFrame() is returning 0.Can any one help where I am going wrong.
Below is my code.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen(argv[1], "rb");
if (pFile == NULL) {
fputs("File error", stderr);
exit(1);
}
// obtain file size:
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile)
rewind(pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc(sizeof(char) * lSize);
if (buffer == NULL) {
fputs("Memory error", stderr);
exit(2);
}
// copy the file into the buffer:
result = fread(buffer, 1, lSize, pFile);
if (result != lSize) {
fputs("Reading error", stderr);
exit(3);
}
// clean up
fclose(pFile);
IplImage *img;
img = cvCreateImage(cvSize(768, 1280), IPL_DEPTH_8U, 4);
memcpy(img->imageData, buffer, lSize);
cvSaveImage("Displaywindow.png", img);
int width = img->width;
int height = img->height;
CvVideoWriter *writer = cvCreateVideoWriter("out.avi",
CV_FOURCC_DEFAULT,
30,
cvSize(height, width), 1);
if(writer == NULL)
{
printf("error\n");
exit(0);
}
for(int counter=0;counter < 3000;counter++)
{
if(cvWriteFrame(writer,img) == 0)
{
printf("con't write\n");
exit(0);
}
}
waitKey(0);
return 0;
}
I am passing my raw file as argument.
I want to open a binary file in C++.
but I have this function in C:
uint openPacket(const char* filename, unsigned char** buffer) {
FILE* fp = fopen(filename, "rb");
if (fp) {
size_t result;
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
rewind(fp);
*buffer = new unsigned char[fsize];
result = fread(*buffer, 1, fsize, fp);
if (result != fsize) {
printf("Reading error in %s, unable to send packet!\n", filename);
delete[] * buffer;
fsize = 0;
}
fclose(fp);
return fsize;
} else {
printf("Couldn't open %s for packet reading, unable to send packet!\n", filename);
return 0;
}
}
I want to make something like: string OpenPacket(string filename)
but don't work :(
May be this is a possible wrapper function:
std::string openPacket( const std::string& filename )
{
unsigned char* buff;
uint size = openPacket( filename.c_str(), &buff );
if( size )
{
std::string s( reinterpret_cast<const char*>(buff), size );
delete [] buff;
return s;
}
return std::string();
}
I think You Need this:
uint openPacket(const char* filename, unsigned char** buffer) {
ifstream file (filename, ios::in|ios::binary|ios::ate);
streampos size;
if (file.is_open())
{
size = file.tellg();
*buffer = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "the entire file content is in memory";
return size;
}
For reference Check this
hope this will help you.
i'm having a weird problem with allocating memory in c++
i'm creating a buffer and read file content into it.
problem is the allocating is incorrect and at the end of the printing there are weird chars...
the content of the file is "Hello"...
i'm sitting on it for hours... what can be the problem ? :(
void main()
{
FILE *fp;
char *buffer;
long file_size;
size_t result;
fp = fopen("input.txt","r");
if (fp == NULL) { fputs("File Error",stderr); exit(1); }
//get file size
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
rewind(fp);
//allocate memory to contain the whole file size
buffer = new char[file_size];
if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }
//copy the file into the buffer
result = fread(buffer, 1, file_size, fp);
if (result != file_size) { fputs("Reading error",stderr); exit(3); }
cout<<buffer;
fclose(fp);
delete buffer;
}
You are not zero-terminating your buffer, so it's not a valid C/C++ string.
Try the following changes:
//allocate memory to contain the whole file size, plus one char for termination
buffer = new char[file_size + 1];
if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }
//copy the file into the buffer
result = fread(buffer, 1, file_size, fp);
if (result != file_size) { fputs("Reading error",stderr); exit(3); }
// terminate buffer, so it becomes a valid string we can print
buffer[file_size] = '\0';
cout<<buffer;
Allocate one more place for termination character. And put it at the end of your buffer.
This will probably solve your problem.
buffer = new char[file_size + 1];
buffer[file_size] ='\0';
buffer must contain a NULL terminated string for your cout<<buffer output to make sense.
When you are in C++, what speaks against using C++?
see: http://www.cplusplus.com/doc/tutorial/files/
edit2: in response to Neil (the initial version printed an empty line 0):
int main () {
std::ifstream i ("main.cpp");
std::string str;
for (int line=0; getline (i, str); ++line) {
std::cout << line << ':' << str << '\n';
}
}