how to read from binary file into struct c? - c

i have the following struct
struct
{
char order;
int row;
int column;
int length;
char printChar;
}record;
and my file look's like this
F
30
40
7
X
how can i use fread to store the file in the struct?
does my file appear correctly or should all the components need to be in one-line?

If I understand correctly, you're asking if you can do
struct record r;
fread(file, &r, sizeof(r));
or are you forced to use
struct record r;
fread(file, &r.order, sizeof(r.order));
If this is your question, then the answer is: you have to read the fields one-by-one since there may be padding between struct members. Or, if you use a GNU-compatible compiler, you might instruct it not to include any padding by declaring your struct as "packed":
struct record {
// ...
} __attribute__((packed));
But this is not advised unless absolutely necessary (it's not portable).
Also, is your file really a binary file? If not, you should pay attention to newline characters and converting the numbers from text to their actual numeric value.

It is not possible to read from a file in that format (essentially containing the character representations of the data) into the structure. One method for reading it would be to use fgets and read each line and assign the data into the structure (converting numeric values as necessary with functions such as strtol or perhaps atoi if error checking is not as important).

Your file seems to be a text file, so if that's exactly the format of the file, you can use fscanf:
fscanf(file, "%c%d%d%d%c", &(record.order), &(record.row), ...
You can check the return value if you're interested in basic error handling. If you need a better description of the error, just use fgets to read one line at a time and parse it with sscanf, atoi, strtol and similar functions.
If you want to directly save data in the structure, no, you can't (with that kind of file), in a text file 30 is a string of two characters, not an integer in binary form.

Related

How to save single line from file to two different strings¸in struct >> line format(NAME#SURNAME AGE)

So i have task to output to one file certain things from another file... Lets say input file is in format
(NAME#SURNAME AGE) with 100 lines and i have to output persons that are older then 15 in this format
(NAME AGE SURNAME) and i have something like this in struct
struct person
{
char name[10];
char surname[10];
int age;
};
Can I, and if I can how can I fread my input file to that struct (file is binary)
If you want more help about the code please do a first version and edit you question, then add a comment and the community will help you.
But if you are looking for the methodology you can go with something like that :
Open the file you want to extract data in read mode (e.g. fopen(filename, "r"))
Check if the file was correctly open
Use a while and take N characters with fgets() or use getline() (Note that getline() is in ISO/IEC TR 24731-2:2010 extension (see n1248).).There is lots of threads about how to read line by line in a file (e.g. Going through a text file line by line in C)
Now you are looking for a way to split your line with delimiters, your can use strtok(), strsep()/strpbrk() or you can do your own implementation of a simple string delimiter (Maybe look this question)
Next the AGE part, you wan to only copy the line with an AGE superior to 15, so use strtol() to convert your string to long int then check the value.Don't use atoi() this function is deprecated).
The atoi() function has been deprecated by strtol() and should not be used in new code.
source Mac OS X Manual Page for atoi(3)
Then you need to create and/or write to a file. You can use fopen(newFilename, "w"), check the file descriptor the function give you in return, if it's ok you can add line with fprintf() (e.g. fprintf(fd, "%s %s %s\r\n", name, age, surname);).
If this is one of your first project/exercise in c take your time to properly understand the function you use and always check the returned values before using them.

Storing a string of inputs into a struct in C

was wondering how I would be able to store a user inputted string in the format "string,character,integer,integer"
into a struct.
For example storing "apple,c,5,10" into
typedef struct {
char item[80];
char letter;
int x,y;
}information;
information apple;
I am trying to avoid going through using scanf and a long piece of code to make the comma into a delimiter so wondering if there was any other way to quickly read from scanf and chucking this information into the struct
You can specify complex formats using scanf, like:
scanf("%79[^,],%c,%d,%d", apple.item, &apple.letter, &apple.x, &apple.y);
%79[^,] means scan anything that is not a comma character, up to 79 characters.
Note that this does no error handling if the user enters a poorly formatted string, like "aaa;b;1;2". For that, you'll need to write a lot more code. See strtok
You can use multiple format specifiers in the format string to scanf() to scan all the input at once, through a comma-seperated user input, like
int ret = -1;
if ((ret = scanf("%79[^,],%c,%d,%d", apple.item, &apple.letter, &apple.x, &apple.y)) != 4)
//always check the return value of scanf()
{
printf("scanf() failed\n");
//do something to avoid usage of the member variables of "apple"
}
However, I'll recommend the long way, like
read the line using fgets()
tokenize using strtok() and , as delimiter
use the token (or convert using strtol(), as required).
Much safe and robust.
Try to read using the func read() then just split the string using strtok()
Here's some references :
strtok : http://man7.org/linux/man-pages/man3/strtok.3.html
read : http://linux.die.net/man/2/read

Reading and comparing numbers from txt file C

I am new to C programming, so I am having difficulties with the problem below.
I have a text file inp.txt which contains information like the following:
400;499;FIRST;
500;599;SECOND;
670;679;THIRD;
I need to type a number and my program needs to compare it with numbers from the inp.txt file.
For example, if I type 450, it's between 400 and 499, so I need write to the word FIRST to the file out.txt
I have no idea how to convert a character array to an int.
I think you'll want these general steps in your program (but I'll leave it to you to figure out how you want to do it exactly)
Load each of the ranges and the text "FIRST", "SECOND", etc. from the file inp.txt, into an array, or several arrays, or similar. As I said in the comment above, fscanf might be handy. This page describes how to use it - the page is about C++, but using it in C should be the same http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/. Roughly speaking, the idea is that you give fscanf a format specifier for what you want to extract from a line in a file, and it puts the bits it finds into the variables you specify)
Prompt the user to enter a number.
Look through the array(s) to work out which range the number fits into, and therefore which text to output
Edit: I'll put some more detail in, as asker requested. This is still a kind of skeleton to give you some ideas.
Use the fopen function, something like this (declare a pointer FILE* input_file):
input_file = fopen("c:\\test\\inp.txt", "r") /* "r" opens inp.txt for reading */
Then, it's good to check that the file was successfully opened, by checking if input_file == NULL.
Then use fscanf to read details from one line of the file. Loop through the lines of the file until you've read the whole thing. You give fscanf pointers to the variables you want it to put the information from each line of the file into. (It's a bit like a printf formatting specifier in reverse).
So, you could declare int range_start, range_end, and char range_name[20]. (To make things simple, let's assume that all the words are at most 20 characters long. This might not be a good plan in the long-run though).
while (!feof(input_file)) { /* check for end-of-file */
if(fscanf(input_file, "%d;%d;%s", &range_start, &range_end, range_name) != 3) {
break; /* Something weird happened on this line, so let's give up */
else {
printf("I got the following numbers: %d, %d, %s\n", range_start, range_end, range_name);
}
}
Hopefully that gives you a few ideas. I've tried running this code and it did seem to work. However, worth saying that fscanf has some drawbacks (see e.g. http://mrx.net/c/readfunctions.html), so another approach is to use fgets to get each line (the advantage of fgets is that you get to specify a maximum number of characters to read, so there's no danger of overrunning a string buffer length) and then sscanf to read from the string into your integer variables. I haven't tried this way though.

Read a binary file C programming

I'm doing a program to manage a clinic, but I'm having a problem. I need to read a binary file with the information from the Doctors. The information is name, code and telephone. They are inserted by the user.
How can I printf that info separately. For example:
Name: John Cruz
Code: JC
Telephone: 90832324
I'm trying to use
typedef struct {
char code[10];
char name[100];
int telephone;
} DOCTOR;
int newDoctor() {//This is the function that create the binary file
DOCTOR d;
FILE *fp;
fp = fopen("Doctors.dat","wb");
if(fp==NULL) {
printf("Error!");
return -1;
}
printf("Code\n");
fflush(stdin);
gets(d.code);
printf("Name\n");
gets(d.name);
printf("Telephone\n");
scanf("%d",&d.telephone);
fprintf(fp,"%s;%s;%d",d.code,d.name, d.telephone);
fclose(fp);
}
//And to open
FILE* fp;
fp=fopen("Doctors.dat","rb");
while(!EOF(fp)) {
fgets(line, 100, fp);
printf("%s",line);
}
Just to see the line but it's not working, and how i can separate the info?
Regards
fgets assumes that the data is ascii strings. For binary data you need to know the binary format and read the data into the appropriate data structures.
You must know the format the binary is in, such as if you serialized a previous struct then you can read it into a struct of the same type:
typedef struct
{
int stuff;
double things;
} myStruct;
myStruct writeMe = {5, 20.5};
FILE* fp;
fp = fopen("Doctores.dat","wb");
if (fp == NULL) { fputs ("File error", stderr); exit(EXIT_ERROR); }
fwrite(writeMe, 1, sizeof(writeMe), fp);
fclose(fp);
Then later to read:
myStruct readMe;
FILE* fp2;
fp2 = fopen("Doctores.dat","rb");
if (fp2 == NULL) { fputs ("File error", stderr); exit(EXIT_ERROR); }
fread(readMe, 1, sizeof(readMe), fp2);
fclose(fp2);
printf("my int: %i\nmy double: %f", readMe.stuff, readMe.things);
Hope this helps
There are at least two issues here: file & data format and reading a binary file. File format is how the information is organized within the file. Binary reading involves reading the file without any translations.
File and Data Format
For text fields, you need to know the following:
Fixed or variable length field.
Maximum field width.
Representation (null terminated,
fixed length, padded, preceded by
length of string, etc.)
You can't assume anything. Get the format in writing. If you don't understand the writing, have the original author rewrite the documentation or explain it to you.
For integral numeric fields you need to know the following:
Size of number, in bytes.
Endianness: Is first byte the Most
Significant (MSB) or Least
significant (LSB)?
Signed or Unsigned
One's complement or two's complement
Numbers can range from 1 "byte" to at least 8 bytes, depending on the platform. If your platform has a native 32-bit integer but the format is 16-bit, your program will read 16 extra bits from the next field. Not good; bad, very bad.
For floating point: you need to know the representation.
The are many ways to represent a floating point number. Floating point numbers can very in size also. Some platforms use 32-bits, while others use 80 bits or more. Again, assume nothing.
Binary Reading
There are no magic methods in the C and C++ libraries to read your structure correctly in one function call; you will have to assemble the fields yourself. One thorn or bump is the fact that compilers may insert "padding" bytes between fields. This is compiler dependent and the quantity of padding bytes is not standard. It is also known as alignment.
Binary reading involves using fread or std::istream::read. The common method is to allocate a buffer, read a block of data into the buffer, then compose the structures from that buffer based on the file format specification.
Summary
Before reading a binary stream of data, you will need a format specification. There are various ways to represent data and internal data representation varies by platform. Binary data is best read into a buffer, then program structures and variables can be built from the buffer.
Textual representations are simpler to input. If possible, request that the creator of the data file use textual representations of the data. Field separators are useful too. A language like XML helps organize the textual data and provides the format in the data file (but may be too verbose for some applications).

How can I use C to assign user input to a variable?

I am wondering if there is a function I could use in the standard libary. Do I need another library (BTW, I am developing for unix).
See the scanf() function in stdio.h. It takes a format specifier like printf() and pointers to the variables to store the user input in
Use scanf()
Format: int scanf ( const char * format, ... );
Read formatted data from stdin.
Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments. The additional arguments should point to already allocated objects of the type specified by their corresponding format tag within the format string.
Example:
#include <stdio.h>
int main(void)
{
int n;
printf("Enter the value to be stored in n: ");
scanf("%d",&n);
printf("n= %d",n);
}
However have a look at this.
You seems quite new to C so let me add a little something to Prasoon answer, which is quite correct and complete, but maybe hard to understand for a beginner.
When using scanf( const char * format, ... ); in his exemple, Prasoon use :
scanf("%d",&n);
When using this, the "%d" indicate you're going to read an integer (See wikipedia for complete format list ).
The second argument (note that the ... indicates you can send any number of arguments) indicate the address of the variable in which you are gonna stock user entry.
'Tis interesting - two answers so far both suggest scanf(); I wouldn't.
When everything goes right, scanf() is OK. When things go wrong, recovery tends to be hard.
I would normally use fgets() to read the user information for one line into a buffer (character array) first. I would then use sscanf() to collect information from the buffer into the target variables. The big advantage is that if the user types '12Z' when you wanted them to type two numbers, you can tell them what you saw and why it is not what you wanted much better. With scanf(), you can't do that.

Resources