Using fread to read and want to use structures from a binary file in C - fread

I have a binary file and i use this code to read it.
FILE * File;
long Size;
char * buffer;
size_t result;
File = fopen ( "STUD.bin" , "rb" );
fseek (File , 0 , SEEK_END);
Size = ftell (File);
rewind (File);
buffer = (char*) malloc (sizeof(char)*Size);
result = fread (buffer,1,Size,File);
Ii want to use those structures from the binary file.
What code should i use for that?

Your question seems a little unclear. But if the case is that you have a structure in the binary file and want to read it then do the following
struct example abc;
fread(&abc,sizeof(abc),1,File);

Related

How can I read \x1a from a file? [duplicate]

I am attempting to write a bittorrent client. In order to parse the file etc. I need to read a torrent file into memory. I have noticed that fread is not reading the entire file into my buffer. After further investigation it appears that whenever the symbol shown below is encountered in the file, fread stops reading the file. Calling the feof function on the FILE* pointer returns 16 indicating that the end of file has been reached. This occurs no matter where the symbol is placed. Can somebody explain why this happens and any solutions that may work.
The symbol is highlighted below:
Here is the code that does the read operation:
char *read_file(const char *file, long long *len){
struct stat st;
char *ret = NULL;
FILE *fp;
//store the size/length of the file
if(stat(file, &st)){
return ret;
}
*len = st.st_size;
//open a stream to the specified file
fp = fopen(file, "r");
if(!fp){
return ret;
}
//allocate space in the buffer for the file
ret = (char*)malloc(*len);
if(!ret){
return NULL;
}
//Break down the call to fread into smaller chunks
//to account for a known bug which causes fread to
//behave strangely with large files
//Read the file into the buffer
//fread(ret, 1, *len, fp);
if(*len > 10000){
char *retTemp = NULL;
retTemp = ret;
int remaining = *len;
int read = 0, error = 0;
while(remaining > 1000){
read = fread(retTemp, 1, 1000, fp);
if(read < 1000){
error = feof(fp);
if(error != 0){
printf("Error: %d\n", error);
}
}
retTemp += 1000;
remaining -= 1000;
}
fread(retTemp, 1, remaining, fp);
} else {
fread(ret, 1, *len, fp);
}
//cleanup by closing the file stream
fclose(fp);
return ret;
}
Thank you for your time :)
Your question is oddly relevant as I recently ran into this problem in an application here at work last week!
The ASCII value of this character is decimal 26 (0x1A, \SUB, SUBSTITUTE). This is used to represent the CTRL+Z key sequence or an End-of-File marker.
Change your fopen mode ("In [Text] mode, CTRL+Z is interpreted as an end-of-file character on input.") to get around this on Windows:
fp = fopen(file, "rb"); /* b for 'binary', disables Text-mode translations */
You should open the file in binary mode. Some platforms, in text (default) mode, interpret some bytes as being physical end of file markers.
You're opening the file in text rather than raw/binary mode - the arrow is ASCII for EOF. Specify "rb" rather than just "r" for your fopen call.

How can I read a .gz text file directly in C

I have a log_date.txt file that I wrote some C code around to parse and reduce it. I parse it by using fgets( buffer, 1024, fp ) to read each line into my buffer character array. Everything is based around a text file with newlines, and I read text line by line.
In keeping these logs over time, each one has had gzip -9 done on it resulting in log_20200101.txt.gz
Imagine having a file saved every day and when running my C code to read any chosen one you would have to manually do a gunzip log_20200101.txt.gz beforehand, and when done re-gzip it. Is there a way in C to do an fopen and continue to use all my fgets() but have it happen on a .gz file?
boom
works inherently on both log.txt and log.txt.gz
# include <stdio.h>
# include <stdlib.h>
# include <zlib.h>
# define LL 8192 /* line length maximum */
int main ( int argc, char *argv[] )
{
gzFile fp;
char line[LL];
fp = gzopen( "log.txt.gz", "r" );
gzgets( fp, line, LL );
while ( ! gzeof( fp ) )
{
printf("%s", line );
gzgets( fp, line, LL );
}
gzclose( fp );
return 0;
}

How can I read from stdin instead of the command line?

FILE * file;
file = fopen(argv[2] , "r");
float val;
if (file) {
while (fscanf(file, "%s", str)!=EOF){
val = atof(str);
root = insert(root, val);
}
fclose(file);
}else{
exit(1);
}
That is a section of the code I have right now. Im trying to change it so that it will read from stdin instead of from the command line. For example running the program would be "./a.out x < file.txt" instead of "./a.out x file.txt".
Instead of using fopen() to open a file, use the fdopen() call to obtain a FILE * that sits on top of the file descriptor for standard input. That's file descriptor 0, or you can use the literal STDIN_FILENO from the unistd.h header if you want to make your program easier for someone to read. It will look like this:
file = fdopen(STDIN_FILENO, "r");
The rest of your program stays the same.

What is a FILE * type in Cocoa,and how properly use it?

I'm trying to run Bash commands from my Cocoa APP. And receive the output. I'm executing all that commands, with Admin Privilege.
How to get output from Admin Priveleges bash script, called from Cocoa?
I guess I need FILE * type to store output, but I don't know how to use it.
What is FILE * type? And how should I use it?
FILE * is a C type and it hasn't got anything to do with Cocoa. It is a handle for an opened file. Here is an example:
#include <stdio.h>
int main () {
FILE *file;
file = fopen("myfile.txt", "w"); // open file
if (!file) { // file couldn't be opened
return 1;
}
fputs("fopen example", file); // write to file
fclose(file);
return 0;
}
In Cocoa, you should normally use NSString's and NSData's writeToURL:atomically:encoding:error: and writeToURL:atomically: methods, respectively.
FILE is an ANSI C structure is used for file handling. fopen function return a file pointer. This pointer, points to a structure that contains information about the file, such as the location of a buffer, the current character position in the buffer, whether the file is being read or written, and whether errors or end of file have occurred. Users don't need to know the details, because the definitions obtained from stdio.h include a structure declaration called FILE. The only declaration needed for a file pointer is exemplified by
FILE *fp;
FILE *fopen(char *name, char *mode);
This says that fp is a pointer to a FILE, and fopen returns a pointer to a FILE. Notice that
FILE is a type name, like int, not a structure tag; it is defined with a typedef.
#include <stdio.h>
int main()
{
FILE * pFile;
char buffer [100];
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else
{
while ( ! feof (pFile) )
{
if ( fgets (buffer , 100 , pFile) != NULL )
fputs (buffer , stdout);
}
fclose (pFile);
}
return 0;
}
This example reads the content of a text file called myfile.txt and sends it to the standard output stream.

GNU Radio File Format for the recorded samples

Do you know the format in which GNU Radio ( File Sink in GNU Radio Companion) stores the samples in the Binary File?
I need to read these samples in Matlab, but the problem is the file is too big to be read in Matlab.
I am writing the program in C++ to read this binary file.
The file sink is just a dump of the data stream. If the data stream content was simple bytes then the content of the file is straightforward. If the data stream contained complex numbers then the file will contain a list of complex numbers where each complex number is given by two floats and each float by (usually) 4 bytes.
See the files gnuradio/gnuradio-core/src/lib/io/gr_file_sink.cc and gr_file_source.cc for the implementations of the gnuradio file reading and writing blocks.
You could also use python and gnuradio to convert the files into some other format.
from gnuradio import gr
# Assuming the data stream was complex numbers.
src = gr.file_source(gr.sizeof_gr_complex, "the_file_name")
snk = gr.vector_sink_c()
tb = gr.top_block()
tb.connect(src, snk)
tb.run()
# The complex numbers are then accessible as a python list.
data = snk.data()
Ben's answer still stands – but it's from a time long past (the module organization points at GNU Radio 3.6, I think). Organizationally, things are different now; data-wise, the File Sink remained the same.
GNU Radio now has relatively much block documentation in their wiki. In particular, the File Sink documentation page has a section on Handling File Sink data; not to overquote that:
// This is C++17
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <string_view>
#include <vector>
#include <fmt/format.h>
#include <fmt/ranges.h>
using sample_t = std::complex<float>;
using power_t = float;
constexpr std::size_t read_block_size = 1 << 16;
int main(int argc, char *argv[]) {
// expect exactly one argument, a file name
if (argc != 2) {
fmt::print(stderr, "Usage: {} FILE_NAME", argv[0]);
return -1;
}
// just for convenience; we could as well just use `argv[1]` throughout the
// code
std::string_view filename(argv[1]);
// check whether file exists
if (!std::filesystem::exists(filename.data())) {
fmt::print(stderr, "file '{:s}' not found\n", filename);
return -2;
}
// calculate how many samples to read
auto file_size = std::filesystem::file_size(std::filesystem::path(filename));
auto samples_to_read = file_size / sizeof(sample_t);
// construct and reserve container for resulting powers
std::vector<power_t> powers;
powers.reserve(samples_to_read);
std::ifstream input_file(filename.data(), std::ios_base::binary);
if (!input_file) {
fmt::print(stderr, "error opening '{:s}'\n", filename);
return -3;
}
// construct and reserve container for read samples
// if read_block_size == 0, then read the whole file at once
std::vector<sample_t> samples;
if (read_block_size)
samples.resize(read_block_size);
else
samples.resize(samples_to_read);
fmt::print(stderr, "Reading {:d} samples…\n", samples_to_read);
while (samples_to_read) {
auto read_now = std::min(samples_to_read, samples.size());
input_file.read(reinterpret_cast<char *>(samples.data()),
read_now * sizeof(sample_t));
for (size_t idx = 0; idx < read_now; ++idx) {
auto magnitude = std::abs(samples[idx]);
powers.push_back(magnitude * magnitude);
}
samples_to_read -= read_now;
}
// we're not actually doing anything with the data. Let's print it!
fmt::print("Power\n{}\n", fmt::join(powers, "\n"));
}