C Lang Newb: My goal: Using a character stream using getchar() into an array and write array to a binary file, and then retrieve binary file into array and output string on console. I was successful with all parts except the output to console.
Call to function:
if (c == '6')
loadDoc();
Write file function:
int saveDoc(char document[MAXSIZE], int size){
FILE *f;
f = fopen("document.bin", "wb");
if (!f) {
printf("Error during writing to file !\n");
}
else{
fwrite(&document, sizeof(document), size, f);
fclose(f);
}
return 0;
}
Read file function:
char loadDoc(){
char buffer[1000];
FILE *f;
f = fopen("document.bin", "rb");
if (!f) {
printf("Error during reading file !\n");
}
else {
printf("Size of buffer: %d\n", sizeof(buffer));
fread(&buffer, sizeof(buffer), 1, f);
printf("File cpntents: \n %s\n", buffer);
fclose(f);
}
return 0;
}
Output:
********************
1) Start New Document:
2) View Document:
3) Edit Document:
4) Delete Document:
5) Save Document:
6) Load Document:
7) Exit
********************
6
Size of buffer: 1000
File cpntents:
#p#
When I open file in notebook, actual content of file is:
#p# & P ÿÿÿÿ& ðýb µ# ú ~ù 3 ÿÿÿÿÿÿÿÿ1 þb B# 3 è# 3 =A
The input entered into file saved and expected output to console with file is read:
This code isn't working as expected.
Here is the correct working solution in GCC:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void save_to_binary_file(const char* file_name, const char* text_data)
{
FILE* file = fopen(file_name, "wb");
if(file == NULL)
printf("Failed to open file %s\n", file_name);
if(fwrite(text_data, sizeof(char), strlen(text_data) + 1, file) != (strlen(text_data) + 1))
puts("Failed to write all text data\n");
fclose(file);
}
char* load_binary_file_as_text(const char* file_name)
{
FILE* file = fopen(file_name, "rb");
if(file == NULL)
printf("Failed to open file %s\n", file_name);
fseek(file, 0, SEEK_END);
size_t file_size_in_bytes = ftell(file);
fseek(file, 0, SEEK_SET);
char* read_buffer = (char*)malloc(file_size_in_bytes);
if(fread(read_buffer, 1, file_size_in_bytes, file) != file_size_in_bytes)
puts("Failed to read all the bytes\n");
fclose(file);
return read_buffer;
}
int main()
{
save_to_binary_file("Data.data", "ABCD");
char* buffer = load_binary_file_as_text("Data.data");
printf("%s\n", buffer);
free(buffer);
return 0;
}
The problem was the '&' in the fwrite() call. Removed it and works as expected.
Related
[Edited and added reprex] When I put the declarations below in the beginning of the main() function, the behavior of the threads is erratic and incorrect. When I make these declarations global, or not the first declarations in main(), everything works fine. I'm using mingw-w64 on Windows 10.
pthread_t thr1, thr2, thr3;
Below is the program, it spawns three threads to read integers from three different text files and add them all to a single global variable. The call to pthread_join() for thr3 always fails with error code 3, and the final result of sum is different in different runs. But it all works fine if the pthread_t declarations are in a different location. I hope this is short enough it's less than 70 lines including whitespace.
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
long sum = 0;
pthread_mutex_t sumLock = PTHREAD_MUTEX_INITIALIZER;
void* thrFunc(void* arg)
{
char curLine[50];
FILE *inFile = fopen((char*)arg, "r");
long curNum;
if (!inFile) {
printf("Error opening input file %s\n", arg);
pthread_exit((void*)1);
}
while (fgets(curLine, sizeof(curLine), inFile)) {
curNum = strtol(curLine, 0, 0);
pthread_mutex_lock(&sumLock);
sum += curNum;
pthread_mutex_unlock(&sumLock);
}
fclose(inFile);
pthread_exit((void*)0);
}
int main(void)
{
pthread_t thr1, thr2, thr3;
long threadResult;
int err;
if (pthread_create(&thr1, 0, thrFunc, (void*)"C:\\Users\\paulc\\long1.txt")) {
printf("Failed to create thread thr1\n");
exit(1);
}
if (pthread_create(&thr2, 0, thrFunc, (void*)"C:\\Users\\paulc\\long2.txt")) {
printf("Failed to create thread thr2\n");
exit(1);
}
if (pthread_create(&thr3, 0, thrFunc, (void*)"C:\\Users\\paulc\\long3.txt")) {
printf("Failed to create thread thr3\n");
exit(1);
}
if (err = pthread_join(thr1, (void**)&threadResult)) {
printf("failed to join thr1, error code = %d\n", err);
}
if (err = pthread_join(thr2, (void**)&threadResult)) {
printf("failed to join thr2, error code = %d\n", err);
}
if (err = pthread_join(thr3, (void**)&threadResult)) {
printf("failed to join thr3, error code = %d\n", err);
}
printf("Total: %ld\n", sum);
}
I'm writing an app that (ab)uses an APL engine, libapl.so. The library contains a mechanism to allow me to capture results, but some stuff it dumps to stdout and stderr. So my question is, is there way a to capture stuff written to stdout rather than having it go to a screen, get piped to another process, or some such? Is there a way, for example, to connect stdout to stdin of the same process? I've tinkered with pipe2(), dup(2), and various bits of weirdness in GTK+/Glib, but I haven't hit the right incantation yet.
Did some more poking--at least one solution seems to be to create a fifo, open() it twice, once for reading, one for writing, and dup2() the writing fd to the stdout fd. This results in writes to stdout going through the fifo pipe where it can be read by the application. (Thanks for some inspiration by someone named Hasturkun, almost 7 years ago.)
Here's a bit of demo code:
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int
main (int ac, char *av[])
{
char tname[64];
sprintf (tname, "/tmp/testpipe%d", (int)getpid ());
int rc = mkfifo (tname, 0666);
if (rc != 0) {
perror ("Creating fifo");
return 1;
}
int temp_in_fd = open (tname, O_NONBLOCK | O_RDONLY);
if (temp_in_fd < 0) {
perror ("Opening new input");
return 1;
}
int temp_out_fd = open (tname, O_NONBLOCK | O_WRONLY);
if (temp_out_fd < 0) {
perror ("Opening new output");
return 1;
}
FILE *temp_in = fdopen (temp_in_fd, "r");
if (!temp_in) {
perror ("Creating new input FILE");
return 1;
}
FILE *temp_out = fdopen (temp_out_fd, "w");
if (!temp_out) {
perror ("Creating new input FILE");
return 1;
}
dup2 (fileno (temp_out), STDOUT_FILENO);
printf("Woot!");
fflush(stdout);
#define BFR_SIZE 64
char bfr[BFR_SIZE];
ssize_t sz = fread (bfr, 1, BFR_SIZE, temp_in);
fprintf (stderr, "got %d bytes: \"%s\"\n", (int)sz, bfr);
fclose (temp_out);
fclose (temp_in);
unlink (tname);
return 0;
}
Here is a example (part of code) from OpenCV (https://docs.opencv.org/3.4.0/d4/da4/group__core__xml.html):
test.yml
%YAML:1.0
---
frameCount: 5
read.cpp
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;
using namespace std;
int main()
{
FileStorage fs("test.yml", FileStorage::READ);
int frameCount = (int) fs["frameCount"];
cout << frameCount << endl;
return 0;
}
Given the code, it works well and reads the yaml file. But when I remove %YAML:1.0, the code throws:
OpenCV Error: Unknown error code -49 (Input file is empty) in cvOpenFileStorage, file /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp, line 4484
terminate called after throwing an instance of 'cv::Exception'
what(): /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp:4484: error: (-49) Input file is empty in function cvOpenFileStorage
[1] 27146 abort (core dumped) ./Read
But I checked the yaml.org. There is no rule stating %YAML:1.0 is necessary. (http://yaml.org/start.html)
**My questions are (updated according to answer from #zindarod ): **
1. Is this OpenCV specific feature??
Yes, this is OpenCV specific requirment.
const char* yaml_signature = "%YAML";
const char* json_signature = "{";
const char* xml_signature = "<?xml";
OpenCV checks the file signature, then decide how to interpret the file.
2. How to know the yaml version I should use??
The yaml verison doesn't matter too much.
But it's better to use 1.0 specification. Probably OpenCV cannot parse other new specifications.
In OpenCV-3.3.1 in function cvOpenFileStorage located at /modules/core/src/persistence.cpp:
...
else
{
if( mem )
{
fs->strbuf = filename;
fs->strbufsize = fnamelen;
}
size_t buf_size = 1 << 20;
const char* yaml_signature = "%YAML";
const char* json_signature = "{";
const char* xml_signature = "<?xml";
char buf[16];
icvGets( fs, buf, sizeof(buf)-2 );
char* bufPtr = cv_skip_BOM(buf);
size_t bufOffset = bufPtr - buf;
if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_YAML;
else if(strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_JSON;
else if(strncmp( bufPtr, xml_signature, strlen(xml_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_XML;
else if(fs->strbufsize == bufOffset)
CV_Error(CV_BADARG_ERR, "Input file is empty");
...
OpenCV checks for file signature (json, yaml and xml). The version of YAML does not matter, as long as the first line contains the string "%YAML" in it.
I've spent hours trying to fix this:
I'm trying to use the ffmpeg api on iOS. My Xcode project is building and I can call ffmpeg api functions. I am trying to write code that decodes a video (Without outputting anything for now), and I keep getting error -35: "Resource temporarily unavailable".
The input file is from the camera roll (.mov) and I'm using Mpeg-4 for decoding. All I'm currently doing is getting data from the file, parsing it and sending the parsed packets to the decoder. When I try to get frames, all I get is an error. Does anyone know what I'm doing wrong?
+(void)test: (NSString*)filename outfile:(NSString*)outfilename {
/* register all the codecs */
avcodec_register_all();
AVCodec *codec;
AVCodecParserContext *parser;
AVCodecContext *c= NULL;
int frame_count;
FILE* f;
AVFrame* frame;
AVPacket* avpkt;
avpkt = av_packet_alloc();
//av_init_packet(avpkt);
char buf[1024];
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data;
size_t data_size;
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
printf("Decode video file %s to %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding], [outfilename cStringUsingEncoding:NSUTF8StringEncoding]);
/* find the h264 video decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen([filename cStringUsingEncoding:NSUTF8StringEncoding], "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding]);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame_count = 0;
parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "parser not found\n");
exit(1);
}
while (!feof(f)) {
/* read raw data from the input file */
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (!data_size)
break;
/* use the parser to split the data into frames */
data = inbuf;
while (data_size > 0) {
int ret = av_parser_parse2(parser, c, &avpkt->data, &avpkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
data += ret;
data_size -= ret;
if (avpkt->size){
char buf[1024];
ret = avcodec_send_packet(c, avpkt);
if (ret < 0) {
fprintf(stderr, "Error sending a packet for decoding\n");
continue;
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_frame(c, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
char e [1024];
av_strerror(ret, e, 1024);
fprintf(stderr, "Fail: %s !\n", e);
// ~~~~~~~~ This is where my program exits ~~~~~~~~~~~~~~~~~~~~~~~~~~~
return;
}
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
}
}
}
}
/* some codecs, such as MPEG, transmit the I and P frame with a
latency of one frame. You must do the following to have a
chance to get the last frame of the video */
fclose(f);
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
printf("\n");
}
AVERROR(EAGAIN) is not an error, it just means output is not yet available and you need to call _send_packet() a few more times before the first output will be available from _receive_frame().
The output is buffered (delayed) to allow for B-frames and frame threading.
I am trying in vs2012 and opencv 2.4.11 to run the objectmaker.exe in my project file which is created by the code and successfully build in release but when i am trying to double click to open it there is a run time error i cant fix it any help please .. my code is :
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
// for filelisting
#include <stdio.h>
#include <io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include "dirent.h"
#include <sys/types.h>
using namespace std;
using namespace cv;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <ENTER>save and load next <ESC>exit";
string IntToString(int num)
{
ostringstream myStream; //creates an ostringstream object
myStream << num << flush;
/*
* outputs the number into the string stream and then flushes
* the buffer (makes sure the output is put into the stream)
*/
return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
if(!startDraw)
{
roi_x0=x;
roi_y0=y;
startDraw = 1;
} else {
roi_x1=x;
roi_y1=y;
startDraw = 0;
}
}
if(event==CV_EVENT_MOUSEMOVE && startDraw)
{
//redraw ROI selection
image2=cvCloneImage(image);
cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),
CV_RGB(255,0,255),1);
cvShowImage(window_name,image2);
cvReleaseImage(&image2);
}
}
int main(int argc, char** argv)
{
int iKey=0;
string strPrefix;
string strPostfix;
string input_directory;
string output_file;
if(argc != 3) {
fprintf(stderr, "%s output_info.txt raw/data/directory/\n", argv[0]);
return -1;
}
input_directory = argv[2];
output_file = argv[1];
/* Get a file listing of all files with in the input directory */
DIR *dir_p = opendir (input_directory.c_str());
struct dirent *dir_entry_p;
if(dir_p == NULL) {
fprintf(stderr, "Failed to open directory %s\n", input_directory.c_str());
return -1;
}
fprintf(stderr, "Object Marker: Input Directory: %s Output File: %s\n", input_directory.c_str(), output_file.c_str());
// init highgui
cvAddSearchPath(input_directory);
cvNamedWindow(window_name,1);
cvSetMouseCallback(window_name,on_mouse, NULL);
fprintf(stderr, "Opening directory...");
// init output of rectangles to the info file
ofstream output(output_file.c_str());
fprintf(stderr, "done.\n");
while((dir_entry_p = readdir(dir_p)) != NULL)
{
numOfRec=0;
if(strcmp(dir_entry_p->d_name, ""))
fprintf(stderr, "Examining file %s\n", dir_entry_p->d_name);
/* TODO: Assign postfix/prefix info */
strPostfix="";
strPrefix=input_directory;
strPrefix+=dir_entry_p->d_name;
//strPrefix+=bmp_file.name;
fprintf(stderr, "Loading image %s\n", strPrefix.c_str());
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
{
// work on current image
do
{
cvShowImage(window_name,image);
// used cvWaitKey returns:
// <Enter>=13 save added rectangles and show next image
// <ESC>=27 exit program
// <Space>=32 add rectangle to current image
// any other key clears rectangle drawing only
iKey=cvWaitKey(0);
switch(iKey)
{
case 27:
cvReleaseImage(&image);
cvDestroyWindow(window_name);
return 0;
case 32:
numOfRec++;
printf(" %d. rect x=%d\ty=%d\tx2h=%d\ty2=%d\n",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
//printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// currently two draw directions possible:
// from top left to bottom right or vice versa
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
}
if(roi_x0>roi_x1 && roi_y0>roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString(roi_y0-roi_y1);
}
break;
}
}
while(iKey!=13);
// save to info file as later used for HaarTraining:
// <rel_path>\bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
if(numOfRec>0 && iKey==13)
{
//append line
/* TODO: Store output information. */
output << strPrefix << " "<< numOfRec << strPostfix <<"\n";
}
cvReleaseImage(&image);
} else {
fprintf(stderr, "Failed to load image, %s\n", strPrefix.c_str());
}
}
output.close();
cvDestroyWindow(window_name);
closedir(dir_p);
return 0;
}