fwrite fails on big data - c++

Hey just try to compile an image in code and put it out as jpg again but fwrite returns 0 and img.jpg keeps empty :(
#include <stdio.h>
#include <string>
#include <iostream>
size_t count = 76830;//=length of data
const uint8_t data[] = {0xff,0xd8,0xff,0xe0,0x0,0x10,0x4a,0x46,0x49,0x46.....
0x0,0x7f,0xff,0xd9};
using namespace std;
//use this to saveToFile...
void saveToFile(const char * filename) {
FILE * file = fopen(filename, "rb");
if (file == NULL) {
std::cout << "error opening file" << std::endl;
return;
}
cout << endl << fwrite(data, sizeof(uint8_t), sizeof(data), file); //this line returns 0!!!
fclose(file);
}
int main () {
saveToFile("img.jpg");
}

fopen(filename, "rb");
This opens the file for reading, not writing. You want
fopen(filename, "wb");
// ^

Related

C++ vector change in text.txt file and add text

#include <iostream>
#include <string>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <vector>
#include <iterator>
using std::cout;
using std::cin;
using std::endl;
using std::string;
std::string FilesOpen(std::string command)
{
const int size_buffer = 2;
char buffer[size_buffer];
memset(buffer, 0, size_buffer * sizeof(char));
std::string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe)
{
return "popen failed!";
}
// read till end of process:
while (!feof(pipe))
{
// use buffer to read and add to result
if (fgets(buffer, 2, pipe) != NULL)
{
result += buffer;
memset(buffer, 0, size_buffer * sizeof(char));
}
}
pclose(pipe);
return result;
}
int main(int* agrc, char* agrv[])
{
std::vector<std::string> pole;
std::string text;
// get files names and use to ifstream files
FilesOpen("ls /root/workspace/src/server > /root/workspace/filestext.txt");
// get files info size and names
FilesOpen("ls -l /root/workspace/src/server > /root/workspace/filelist.txt");
// get files name and add vector
std::ifstream files;
files.open("/root/workspace/filestext.txt", std::ios_base::in);
if (!files)
{
std::cout << "Error not open files" << std::endl;
}
while (files >> text)
{
pole.push_back(text);
}
files.close();
for (std::vector<std::string>::iterator it = pole.begin(); it != pole.end(); ++it)
{
std::cout << *it << std::endl;
}
// replace text in shell
std::string filereplace = "/root/workspace/testovaci.sh";
std::ofstream r_file(filereplace.c_str());
char patch[] = "patch=";
if (r_file.is_open())
{
for (int i = 0; patch[i] != '\0'; i++)
r_file.put(patch[i]);
r_file.put('D');
}
r_file.close()
}
I need to get the contents of the file name from the filetext.txt file and ignore the folders and list them in the testovaci.sh script, which looks like this:
neco1
neco2
neco3
patch =
neco4
neco5
I need to put in the testovaci.sh file has been added to patch = "file". "file". "file"
and the folders were ignored, leaving only binary files.
Please help me, as I tried everything but nothing works.

Store contents of text file in a char* array in C++

I have to read the contents of a file, and store them in a char* array. I have the following, but when I output my char* array I don't get the full output of the file I read in. Am I incorrectly calculating the file size of my output array?
Note: I must use POSIX calls to read the contents of the file.
#include "iostream"
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main() {
const char* name = "test.txt";
int fd = open(name, O_RDONLY);
off_t length = lseek(fd, 0, SEEK_END);
cout << "file size: " << length << endl;
char* array = new char[length];
lseek(fd, 0, SEEK_SET); // resets position to 0
read(fd, array, sizeof(array)-1);
cout << array << "finished" << endl;
close(fd);
delete[] array;
return 0;
}
Contents of test.txt are This is a string of sample text
But this is my output when running:
file size: 34
This isfinished

How do I double each character in a file?

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FILE_READ "prive.txt"
int main() {
FILE * filp;
int count = 1;
char c;
filp = fopen(FILE_READ, "r");
if (filp == NULL)
printf("file not found\n");
while((c = fgetc(filp)) != EOF) {
for (int i = 0; i < strlen(c); i++){
strncpy()
}
}
printf("worrds = %s\n", c);
return 0;
}
How do I double each character in a file?
Example:
Before: Hi
After: HHii
One more example:
Hello
HHeelllloo
Use std::ifstream and std::ofstream to open the input and output file buffers. Use std::istream::get to retrieve each char of the file and then output it twice to your FILE_WRITE.
#include <iostream>
#include <fstream>
#define FILE_READ "./prive.txt"
#define FILE_WRITE "./output.txt"
int main()
{
char c;
std::ifstream i(FILE_READ);
std::ofstream o(FILE_WRITE);
while (i.get(c))
o << c << c;
i.close();
o.close();
return 0;
}
And since you asked, if you would not like to use fstream, you could go for the solution below, which adds the input and output files to a buffer with fopen(), and by means of fgetc() stores each char of the text file in the c variable. Then, by means of fprintf(), the char is added twice to the output file.
#include <iostream>
#define FILE_READ "./prive.txt"
#define FILE_WRITE "./output.txt"
int main()
{
FILE* input = fopen(FILE_READ, "r");
FILE* output = fopen(FILE_WRITE, "w");
signed char c;
while ((c = fgetc(input)) != EOF) {
fprintf(output, "%c%c", c, c);
}
fclose(input);
fclose(output);
return 0;
}
This program opens the file input.txt and prints each character twice into output.txt. That also means that each line break is duplicated though.
Example of the input.txt file:
Hello, World!
Example of the output.txt file:
HHeelllloo,, WWoorrlldd!!
Using <iostream> and <fstream>
#include <iostream>
#include <fstream>
int main(void)
{
char c;
std::ifstream file_in("input.txt");
std::ofstream file_out("output.txt");
if (!file_in.is_open() || !file_out.is_open()) {
std::cout << "Unable to open file.\n";
exit(EXIT_FAILURE);
}
while (file_in.get(c)) {
file_out << c << c;
}
file_in.close();
file_out.close();
return EXIT_SUCCESS;
}
Using <stdio.h> and <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c;
FILE *file_in = fopen("input.txt", "r");
FILE *file_out = fopen("output.txt", "w");
if (!file_in || !file_out) {
printf("Unable to open file.\n");
exit(EXIT_FAILURE);
}
while ((c = fgetc(file_in)) != EOF) {
fprintf(file_out, "%c%c", c, c);
}
fclose(file_in);
fclose(file_out);
return EXIT_SUCCESS;
}
Open the input file in "read" mode;
Open an output file in "write" mode;
Read one character from the input file until reach EOF:
Write the character to the output file;
Repeat the write operation;
Close both files.
[Optional] remove the input file, rename the output file to the original name.

Write vector of unsigned char to binary file c++

I am reading binary file cmd.exe into unsigned chars array. Total bytes read into bytes_read are 153. I converted it to base64 string and then decode this string back (code from 2nd answer base64 decode snippet in c++) into vector<'BYTE>. Here BYTE is unsigned char.
decodedData.size() is also 153. But when I write this vector to file in binary mode to get my cmd.exe file again I get only 1 KB file. What thing I missed?
// Reading size of file
FILE * file = fopen("cmd.exe", "r+");
if (file == NULL) return 1;
fseek(file, 0, SEEK_END);
long int size = ftell(file);
fclose(file);
// Reading data to array of unsigned chars
file = fopen("cmd.exe", "r+");
unsigned char * myData = (unsigned char *)malloc(size);
int bytes_read = fread(myData, sizeof(unsigned char), size, file);
fclose(file);
std::string encodedData = base64_encode(&myData[0], bytes_read);
std::vector<BYTE> decodedData = base64_decode(encodedData);
////write data to file
ofstream outfile("cmd.exe", ios::out | ios::binary);
outfile.write((const char *)decodedData.data(), decodedData.size());
Update:
Thanks #chux for suggesting "r+" --> "rb+" Problem resolved.
You marked this as C++.
This is one C++ approach using fstream to read a binary file. To simplify for this example, I created a somewhat bigger m_buff than needed. From the comments, it sounds like your fopen("cmd.exe", "r+") was in error, so I'm only providing a C++ binary read.
Method tReader() a) opens a file in binary mode, b) reads the data into m_buff, and c) captures gCount for display.
It also demonstrates one possible use of chrono to measure duration.
#include <chrono>
// 'compressed' chrono access --------------vvvvvvv
typedef std::chrono::high_resolution_clock HRClk_t;
typedef HRClk_t::time_point Time_t;
typedef std::chrono::microseconds US_t;
using namespace std::chrono_literals; // suffixes 100ms, 2s, 30us
#include <iostream>
#include <fstream>
#include <cassert>
class T516_t
{
enum BuffConstraints : uint32_t {
Meg = (1024 * 1024),
END_BuffConstraints
};
char* m_buff;
int64_t m_gCount;
public:
T516_t()
: m_buff (nullptr)
, m_gCount (0)
{
m_buff = new char[Meg];
}
~T516_t() = default;
int exec()
{
tReader();
return(0);
}
private: // methods
void tReader()
{
std::string pfn = "/home/dmoen/.wine/drive_c/windows/system32/cmd.exe";
// open file in binary mode
std::ifstream sIn (pfn, std::ios_base::binary);
if (!sIn.is_open()) {
std::cerr << "UNREACHABLE: unable to open sIn " << pfn
<< " priviledges? media offline?";
return;
}
Time_t start_us = HRClk_t::now();
do
{
// perform read
sIn.read (m_buff, Meg);
// If the input sequence runs out of characters to extract (i.e., the
// end-of-file is reached) before n characters have been successfully
// read, buff contains all the characters read until that point, and
// both eofbit and failbit flags are set
m_gCount = sIn.gcount();
if(sIn.eof()) { break; } // exit when no more data
if(sIn.failbit ) {
std::cerr << "sIn.faileBit() set" << std::endl;
}
}while(1);
auto duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);
sIn.close();
std::cout << "\n " << pfn
<< " " << m_gCount << " bytes"
<< " " << duration_us.count() << " us"
<< std::endl;
} // int64_t tReader()
}; // class T516_t
int main(int , char**)
{
Time_t start_us = HRClk_t::now();
int retVal = -1;
{
T516_t t516;
retVal = t516.exec();
}
auto duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);
std::cout << " FINI " << duration_us.count() << " us" << std::endl;
return(retVal);
}
One typical output on my system looks like:
/home/dmoen/.wine/drive_c/windows/system32/cmd.exe 722260 bytes 1180 us
FINI 1417 us
Your results will vary.
Your ofstream use looks good (so did not replicate).

Size is always zero when reading DRM EDID file

I tried to read the EDID of my monitor connected to LVDS1. I use ArchLinux and C++/clang. My problem is: the file size always returns 0. I don't know if this is a programming problem or something OS specific, other files return a proper file size. Is it a special file? Is the symlink directory /sys/class/drm/card0-DP-1 the problem?
file: /sys/class/drm/card0-LVDS-1/edid
code:
#include <fstream>
#include <iostream>
using namespace std;
typedef unsigned char BYTE;
long
get_file_size(FILE *f)
{
long pos_cursor, pos_end;
pos_cursor = ftell(f);
fseek(f, 0, 2);
pos_end = ftell(f);
fseek(f, pos_cursor, 0);
return pos_end;
}
int
main()
{
const char *filepath = "/sys/class/drm/card0-LVDS-1/edid";
FILE *file = NULL;
if((file = fopen(filepath, "rb")) == NULL)
{
cout << "file could not be opened" << endl;
return 1;
}
else
cout << "file opened" << endl;
long filesize = get_file_size(file);
cout << "file size: " << filesize << endl;
fclose(file);
return 0;
}
output:
file opened
file size: 0
===
as suggested by MSalters, I tried stat for the file size. Also returns 0. I assume the code is correct, so it is somehow just not possible to access the file?
I also tried the symlink target path (/sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/edid), just in case that was the problem - but still 0.
code:
#include <iostream>
#include <sys/stat.h>
using namespace std;
int
main()
{
const char *filepath = "/sys/class/drm/card0-LVDS-1/edid";
struct stat results;
if (stat(filepath, &results) == 0)
cout << results.st_size << endl;
else
cout << "error" << endl;
return 0;
}
output
0
===
I tried other files in the same directory (dpms edid enabled i2c-6 modes power status subsystem uevent). They all return a filesize of 4096 except edid.
I suspect that fseek(f, 0, 2); might mean fseek(f, 0, SEEK_CUR); which obviously doesn't do anything. You'd want SEEK_END which isn't portable, but then again /sys/ isn't either. (Of course, do #include <stdio.h>)
But considering it's already Linux-specific, why not use stat ?