How to create a linked list from a binary input file? With first few bytes being an int and the next few a char and so onWhy is “while (!feof(file))” always wrong?How do I create a Java string from the contents of a file?How to create a linked list of nodes that are contained in the max-Depth of a Binary Tree using JavaSegmentation fault when inserting values from file into linked listhow to read in file that contains char, int and white space into linked listHow do I create an array of multiple linked lists in c?C Linked List - Linking next Linked List NodeUnexpected behaviour of fread() reading from binary fileGetting all chars in text file by fscanf() returns invalid count of charLinked list issue from reading a file cHow to convert a binary file to a text file, containing ints and chars

Picking a theme as a discovery writer

As a GM, is it bad form to ask for a moment to think when improvising?

Find the area of the smallest rectangle to contain squares of sizes up to n

While drilling into kitchen wall, hit a wire - any advice?

All of my Firefox add-ons been disabled suddenly, how can I re-enable them?

Changing stroke width vertically but not horizontally in Inkscape

Can I combine SELECT TOP() with the IN operator?

A 2-connected graph contains a path passing through all the odd degree vertices

Can an Iranian citizen enter the USA on a Dutch passport?

How do I, as a DM, handle a party that decides to set up an ambush in a dungeon?

Transistor gain, what if there is not enough current?

Two denim hijabs

Why are condenser mics so much more expensive than dynamics?

Where did Lovecraft write about Carcosa?

What does the phrase "go for the pin" mean here?

hl with custom color and linebreak and math

What does のそ mean on this picture?

Debian 9 server no sshd in auth.log

When did England stop being a Papal fief?

What do you call a painting painted on a wall?

How to speed up large double sums in a table?

Primes in a Diamond

What is the thing used to help pouring liquids called?

Is throwing dice a stochastic or a deterministic process?



How to create a linked list from a binary input file? With first few bytes being an int and the next few a char and so on


Why is “while (!feof(file))” always wrong?How do I create a Java string from the contents of a file?How to create a linked list of nodes that are contained in the max-Depth of a Binary Tree using JavaSegmentation fault when inserting values from file into linked listhow to read in file that contains char, int and white space into linked listHow do I create an array of multiple linked lists in c?C Linked List - Linking next Linked List NodeUnexpected behaviour of fread() reading from binary fileGetting all chars in text file by fscanf() returns invalid count of charLinked list issue from reading a file cHow to convert a binary file to a text file, containing ints and chars






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








-3















I want to create a linked list from an input binary file. The first sizeof(int) bytes is an int and the next sizeof(char) bytes is a char and it keeps going like that.
What I want to do is create a linked list from this file where each node in the linked list contains a character and a tree node that contains this int value.



I am stuck when it comes to creating a linked list out of this file. If it was just a regular file with ints and no binary and no chars, I would have used fscanf to read the file and stored its contents into an array, and then I would have traversed through the array and made the nodes. However, I am confused when these chars are present in the file. Could anyone please help me and tell me if there is a way to create a linked list?



Edits ->



ListNode *head = malloc(sizeof(ListNode)*sizeoffile);

//how do i find the size of the file.
//if it was a file with just integers, I would have done something like this
// int value;
// int count = 0;
//while(fscanf(fptr, "%d", &value)==1)
//
// count++;
//
//But now that there is chars, I am really confused how I would determine
//the size of the file.

while(!feof(fptr))

fread(head, sizeof(int)+sizeof(char), 1, fptr);


I know this is not right. ^









share|improve this question
























  • Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

    – melpomene
    Mar 23 at 5:24











  • If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

    – Costantino Grana
    Mar 23 at 7:05











  • @melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

    – noobie
    Mar 24 at 0:41











  • @CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

    – noobie
    Mar 24 at 0:56


















-3















I want to create a linked list from an input binary file. The first sizeof(int) bytes is an int and the next sizeof(char) bytes is a char and it keeps going like that.
What I want to do is create a linked list from this file where each node in the linked list contains a character and a tree node that contains this int value.



I am stuck when it comes to creating a linked list out of this file. If it was just a regular file with ints and no binary and no chars, I would have used fscanf to read the file and stored its contents into an array, and then I would have traversed through the array and made the nodes. However, I am confused when these chars are present in the file. Could anyone please help me and tell me if there is a way to create a linked list?



Edits ->



ListNode *head = malloc(sizeof(ListNode)*sizeoffile);

//how do i find the size of the file.
//if it was a file with just integers, I would have done something like this
// int value;
// int count = 0;
//while(fscanf(fptr, "%d", &value)==1)
//
// count++;
//
//But now that there is chars, I am really confused how I would determine
//the size of the file.

while(!feof(fptr))

fread(head, sizeof(int)+sizeof(char), 1, fptr);


I know this is not right. ^









share|improve this question
























  • Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

    – melpomene
    Mar 23 at 5:24











  • If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

    – Costantino Grana
    Mar 23 at 7:05











  • @melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

    – noobie
    Mar 24 at 0:41











  • @CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

    – noobie
    Mar 24 at 0:56














-3












-3








-3


1






I want to create a linked list from an input binary file. The first sizeof(int) bytes is an int and the next sizeof(char) bytes is a char and it keeps going like that.
What I want to do is create a linked list from this file where each node in the linked list contains a character and a tree node that contains this int value.



I am stuck when it comes to creating a linked list out of this file. If it was just a regular file with ints and no binary and no chars, I would have used fscanf to read the file and stored its contents into an array, and then I would have traversed through the array and made the nodes. However, I am confused when these chars are present in the file. Could anyone please help me and tell me if there is a way to create a linked list?



Edits ->



ListNode *head = malloc(sizeof(ListNode)*sizeoffile);

//how do i find the size of the file.
//if it was a file with just integers, I would have done something like this
// int value;
// int count = 0;
//while(fscanf(fptr, "%d", &value)==1)
//
// count++;
//
//But now that there is chars, I am really confused how I would determine
//the size of the file.

while(!feof(fptr))

fread(head, sizeof(int)+sizeof(char), 1, fptr);


I know this is not right. ^









share|improve this question
















I want to create a linked list from an input binary file. The first sizeof(int) bytes is an int and the next sizeof(char) bytes is a char and it keeps going like that.
What I want to do is create a linked list from this file where each node in the linked list contains a character and a tree node that contains this int value.



I am stuck when it comes to creating a linked list out of this file. If it was just a regular file with ints and no binary and no chars, I would have used fscanf to read the file and stored its contents into an array, and then I would have traversed through the array and made the nodes. However, I am confused when these chars are present in the file. Could anyone please help me and tell me if there is a way to create a linked list?



Edits ->



ListNode *head = malloc(sizeof(ListNode)*sizeoffile);

//how do i find the size of the file.
//if it was a file with just integers, I would have done something like this
// int value;
// int count = 0;
//while(fscanf(fptr, "%d", &value)==1)
//
// count++;
//
//But now that there is chars, I am really confused how I would determine
//the size of the file.

while(!feof(fptr))

fread(head, sizeof(int)+sizeof(char), 1, fptr);


I know this is not right. ^






c file linked-list






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 24 at 0:54







noobie

















asked Mar 23 at 4:33









noobienoobie

12




12












  • Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

    – melpomene
    Mar 23 at 5:24











  • If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

    – Costantino Grana
    Mar 23 at 7:05











  • @melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

    – noobie
    Mar 24 at 0:41











  • @CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

    – noobie
    Mar 24 at 0:56


















  • Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

    – melpomene
    Mar 23 at 5:24











  • If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

    – Costantino Grana
    Mar 23 at 7:05











  • @melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

    – noobie
    Mar 24 at 0:41











  • @CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

    – noobie
    Mar 24 at 0:56

















Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

– melpomene
Mar 23 at 5:24





Technically the answer to your question is "yes" (there is a way to create linked lists). Why do you need to create an array first? If you can traverse an array, you can traverse an input file. Where exactly are you stuck?

– melpomene
Mar 23 at 5:24













If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

– Costantino Grana
Mar 23 at 7:05





If you want an answer, you need to really clarify this question and show some effort. Let's see, you could start editing your question and show us your code for reading one integer and one char from a binary file. Before that show us the hex dump of such a file.

– Costantino Grana
Mar 23 at 7:05













@melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

– noobie
Mar 24 at 0:41





@melpomene I want to traverse the input file and put it into a linked list. I am confused because I dont know how to use fscanf when it is a linked list. Would I use %d or %c in the parameters? I dont know how to put both things into one node. I am confused because the file is a binary file. I am sorry if I am not explaining my problem well.

– noobie
Mar 24 at 0:41













@CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

– noobie
Mar 24 at 0:56






@CostantinoGrana I edited the post to add code. The reason I didn't add code was because I didn't know how to form the code in the first place and I was confused as to how I would go about forming it. I have added some code to make my problem more clear. If you could help, that would be great, I apologize if my question wasn't clear, I am a beginner and I really don't know how to go about solving this problem.

– noobie
Mar 24 at 0:56













3 Answers
3






active

oldest

votes


















1














Step 1: Assume all data from an external source (e.g. from a file) is potentially malicious and/or corrupted and/or came from a different computer (with different sizeof(int) and different endianness).



Step 2: Define your file format properly (taking step 1 into account). E.g. maybe it's supposed to be a value in the range 123 to 123456 that's stored as 4 consecutive bytes in little endian order (it should never be an int); and maybe it's a byte containing an ASCII character (it should never be a "random whatever character set the compiler felt like using char").



Step 3: Write some code to load data from the file into an array of bytes. If the file is expected to be small you can use realloc() to increase the size of the buffer if the buffer wasn't big enough (but make sure there's a "max. file size" so that a malicious attacker can't trick you into consuming all available RAM and crashing due to "out of memory"). If the file is expected to be larger; look into functions like mmap(). Alternatively, you can have a "read next part of file; parse next part of file" loop that recycles a fixed sized buffer.



Step 4: Write code to parse the "array of bytes" data and check that it actually complies with the file format specs in every way possible. For example, unsigned long value = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24) and if( (value < 123) || (value > 123456) ) { // Data is malformed.



Step 5: Once you've parsed the data (and written code to handle every conceivable error condition in an appropriate manner, and know for a fact that it must be valid data), you can store the data in a structure and add that structure to a linked list. E.g.



 // Parse and check it

if(bufferSize < position + 5)
return "File ends in the middle of a record";

unsigned long value = buffer[position] + (buffer[position+1] << 8) + (buffer[position+2] << 16) + (buffer[position+3] << 24);
if( (value < 123) || (value > 123456) )
return "Data was malformed (integer out of range)";


if( (buffer[position+4] < 0x20) || (buffer[position+4] >= 0x7F) )
return "Data was malformed (character not printable ASCII)";


// Create a structure

myStructureType * myStruct = malloc(sizeof(myStructureType));
if(myStruct == NULL)
return "Failed to allocate memory for structure";

myStruct->value = value;
myStruct->character = buffer[position+4];
position += 5;

// Add structure to singly linked list

myStruct->next = NULL;
if(listFirst == NULL)
listFirst = myStruct;
else
listLast->next = myStruct;

listLast = myStruct;





share|improve this answer

























  • This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

    – Ben Zotto
    Mar 24 at 2:34



















0














Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.



The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout one per line representing the integer in base 10 followed by a space and then the character".



Let's assume that your int is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.



Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf and fread. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.



In your code you write



while (!feof(fptr))


This is always wrong. The only correct way for reading a file is:



while (1) 
// Read
// Check
// Use



Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.



So lets populate the above template. To check if fread succeeded you need to check if it returned the number of elements you asked for.



while (1) 


Of course you can pack this in the while condition, but I don't see a reason for that.



Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.



Here I assumed that you didn't learn structs yet. If this is not the case, you can work with them:



struct widget 
int i;
char c;
;

[...]

while (1)
struct widget w;
// Read
int ok1 = fread(&w.i, 4, 1, fptr);
int ok2 = fread(&w.c, 1, 1, fptr);
// Check
if (ok1 != 1


Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that



fread(&w, 5, 1, fptr); // No! Don't do this


will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget) returned 8.



Disclaimer: I wrote the code directly on the browser and didn't check it!






share|improve this answer






























    -1














    I think you are getting a little too caught up in something that isn't really a fundamental problem. if you need to create a linked list from a file, you could use fscanf() or fread() or whatever you like to read a file into a buffer and manipulate that buffer as you wish. The same logic for parsing an array of ints (read in from a file) can be applied to parsing a buffer of strings from a binary file (you say binary file with sizeof(int), sizeof(char) consecutively so I'm going to assume you mean it can be read into a buffer)



    You say




    "If it was just a regular file with ints and no binary and no chars, I
    would have used fscanf to read the file and stored its contents into
    an array, and then I would have traversed through the array and made
    the nodes"




    you can traverse a string, or list of strings (however you decide to parse your buffer) using the same logic to make nodes. That's the beauty of a data structure, or struct if you will, in C.






    share|improve this answer

























    • Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

      – noobie
      Mar 24 at 0:33












    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55310632%2fhow-to-create-a-linked-list-from-a-binary-input-file-with-first-few-bytes-being%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Step 1: Assume all data from an external source (e.g. from a file) is potentially malicious and/or corrupted and/or came from a different computer (with different sizeof(int) and different endianness).



    Step 2: Define your file format properly (taking step 1 into account). E.g. maybe it's supposed to be a value in the range 123 to 123456 that's stored as 4 consecutive bytes in little endian order (it should never be an int); and maybe it's a byte containing an ASCII character (it should never be a "random whatever character set the compiler felt like using char").



    Step 3: Write some code to load data from the file into an array of bytes. If the file is expected to be small you can use realloc() to increase the size of the buffer if the buffer wasn't big enough (but make sure there's a "max. file size" so that a malicious attacker can't trick you into consuming all available RAM and crashing due to "out of memory"). If the file is expected to be larger; look into functions like mmap(). Alternatively, you can have a "read next part of file; parse next part of file" loop that recycles a fixed sized buffer.



    Step 4: Write code to parse the "array of bytes" data and check that it actually complies with the file format specs in every way possible. For example, unsigned long value = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24) and if( (value < 123) || (value > 123456) ) { // Data is malformed.



    Step 5: Once you've parsed the data (and written code to handle every conceivable error condition in an appropriate manner, and know for a fact that it must be valid data), you can store the data in a structure and add that structure to a linked list. E.g.



     // Parse and check it

    if(bufferSize < position + 5)
    return "File ends in the middle of a record";

    unsigned long value = buffer[position] + (buffer[position+1] << 8) + (buffer[position+2] << 16) + (buffer[position+3] << 24);
    if( (value < 123) || (value > 123456) )
    return "Data was malformed (integer out of range)";


    if( (buffer[position+4] < 0x20) || (buffer[position+4] >= 0x7F) )
    return "Data was malformed (character not printable ASCII)";


    // Create a structure

    myStructureType * myStruct = malloc(sizeof(myStructureType));
    if(myStruct == NULL)
    return "Failed to allocate memory for structure";

    myStruct->value = value;
    myStruct->character = buffer[position+4];
    position += 5;

    // Add structure to singly linked list

    myStruct->next = NULL;
    if(listFirst == NULL)
    listFirst = myStruct;
    else
    listLast->next = myStruct;

    listLast = myStruct;





    share|improve this answer

























    • This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

      – Ben Zotto
      Mar 24 at 2:34
















    1














    Step 1: Assume all data from an external source (e.g. from a file) is potentially malicious and/or corrupted and/or came from a different computer (with different sizeof(int) and different endianness).



    Step 2: Define your file format properly (taking step 1 into account). E.g. maybe it's supposed to be a value in the range 123 to 123456 that's stored as 4 consecutive bytes in little endian order (it should never be an int); and maybe it's a byte containing an ASCII character (it should never be a "random whatever character set the compiler felt like using char").



    Step 3: Write some code to load data from the file into an array of bytes. If the file is expected to be small you can use realloc() to increase the size of the buffer if the buffer wasn't big enough (but make sure there's a "max. file size" so that a malicious attacker can't trick you into consuming all available RAM and crashing due to "out of memory"). If the file is expected to be larger; look into functions like mmap(). Alternatively, you can have a "read next part of file; parse next part of file" loop that recycles a fixed sized buffer.



    Step 4: Write code to parse the "array of bytes" data and check that it actually complies with the file format specs in every way possible. For example, unsigned long value = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24) and if( (value < 123) || (value > 123456) ) { // Data is malformed.



    Step 5: Once you've parsed the data (and written code to handle every conceivable error condition in an appropriate manner, and know for a fact that it must be valid data), you can store the data in a structure and add that structure to a linked list. E.g.



     // Parse and check it

    if(bufferSize < position + 5)
    return "File ends in the middle of a record";

    unsigned long value = buffer[position] + (buffer[position+1] << 8) + (buffer[position+2] << 16) + (buffer[position+3] << 24);
    if( (value < 123) || (value > 123456) )
    return "Data was malformed (integer out of range)";


    if( (buffer[position+4] < 0x20) || (buffer[position+4] >= 0x7F) )
    return "Data was malformed (character not printable ASCII)";


    // Create a structure

    myStructureType * myStruct = malloc(sizeof(myStructureType));
    if(myStruct == NULL)
    return "Failed to allocate memory for structure";

    myStruct->value = value;
    myStruct->character = buffer[position+4];
    position += 5;

    // Add structure to singly linked list

    myStruct->next = NULL;
    if(listFirst == NULL)
    listFirst = myStruct;
    else
    listLast->next = myStruct;

    listLast = myStruct;





    share|improve this answer

























    • This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

      – Ben Zotto
      Mar 24 at 2:34














    1












    1








    1







    Step 1: Assume all data from an external source (e.g. from a file) is potentially malicious and/or corrupted and/or came from a different computer (with different sizeof(int) and different endianness).



    Step 2: Define your file format properly (taking step 1 into account). E.g. maybe it's supposed to be a value in the range 123 to 123456 that's stored as 4 consecutive bytes in little endian order (it should never be an int); and maybe it's a byte containing an ASCII character (it should never be a "random whatever character set the compiler felt like using char").



    Step 3: Write some code to load data from the file into an array of bytes. If the file is expected to be small you can use realloc() to increase the size of the buffer if the buffer wasn't big enough (but make sure there's a "max. file size" so that a malicious attacker can't trick you into consuming all available RAM and crashing due to "out of memory"). If the file is expected to be larger; look into functions like mmap(). Alternatively, you can have a "read next part of file; parse next part of file" loop that recycles a fixed sized buffer.



    Step 4: Write code to parse the "array of bytes" data and check that it actually complies with the file format specs in every way possible. For example, unsigned long value = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24) and if( (value < 123) || (value > 123456) ) { // Data is malformed.



    Step 5: Once you've parsed the data (and written code to handle every conceivable error condition in an appropriate manner, and know for a fact that it must be valid data), you can store the data in a structure and add that structure to a linked list. E.g.



     // Parse and check it

    if(bufferSize < position + 5)
    return "File ends in the middle of a record";

    unsigned long value = buffer[position] + (buffer[position+1] << 8) + (buffer[position+2] << 16) + (buffer[position+3] << 24);
    if( (value < 123) || (value > 123456) )
    return "Data was malformed (integer out of range)";


    if( (buffer[position+4] < 0x20) || (buffer[position+4] >= 0x7F) )
    return "Data was malformed (character not printable ASCII)";


    // Create a structure

    myStructureType * myStruct = malloc(sizeof(myStructureType));
    if(myStruct == NULL)
    return "Failed to allocate memory for structure";

    myStruct->value = value;
    myStruct->character = buffer[position+4];
    position += 5;

    // Add structure to singly linked list

    myStruct->next = NULL;
    if(listFirst == NULL)
    listFirst = myStruct;
    else
    listLast->next = myStruct;

    listLast = myStruct;





    share|improve this answer















    Step 1: Assume all data from an external source (e.g. from a file) is potentially malicious and/or corrupted and/or came from a different computer (with different sizeof(int) and different endianness).



    Step 2: Define your file format properly (taking step 1 into account). E.g. maybe it's supposed to be a value in the range 123 to 123456 that's stored as 4 consecutive bytes in little endian order (it should never be an int); and maybe it's a byte containing an ASCII character (it should never be a "random whatever character set the compiler felt like using char").



    Step 3: Write some code to load data from the file into an array of bytes. If the file is expected to be small you can use realloc() to increase the size of the buffer if the buffer wasn't big enough (but make sure there's a "max. file size" so that a malicious attacker can't trick you into consuming all available RAM and crashing due to "out of memory"). If the file is expected to be larger; look into functions like mmap(). Alternatively, you can have a "read next part of file; parse next part of file" loop that recycles a fixed sized buffer.



    Step 4: Write code to parse the "array of bytes" data and check that it actually complies with the file format specs in every way possible. For example, unsigned long value = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24) and if( (value < 123) || (value > 123456) ) { // Data is malformed.



    Step 5: Once you've parsed the data (and written code to handle every conceivable error condition in an appropriate manner, and know for a fact that it must be valid data), you can store the data in a structure and add that structure to a linked list. E.g.



     // Parse and check it

    if(bufferSize < position + 5)
    return "File ends in the middle of a record";

    unsigned long value = buffer[position] + (buffer[position+1] << 8) + (buffer[position+2] << 16) + (buffer[position+3] << 24);
    if( (value < 123) || (value > 123456) )
    return "Data was malformed (integer out of range)";


    if( (buffer[position+4] < 0x20) || (buffer[position+4] >= 0x7F) )
    return "Data was malformed (character not printable ASCII)";


    // Create a structure

    myStructureType * myStruct = malloc(sizeof(myStructureType));
    if(myStruct == NULL)
    return "Failed to allocate memory for structure";

    myStruct->value = value;
    myStruct->character = buffer[position+4];
    position += 5;

    // Add structure to singly linked list

    myStruct->next = NULL;
    if(listFirst == NULL)
    listFirst = myStruct;
    else
    listLast->next = myStruct;

    listLast = myStruct;






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 24 at 2:29

























    answered Mar 24 at 2:16









    BrendanBrendan

    14k1532




    14k1532












    • This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

      – Ben Zotto
      Mar 24 at 2:34


















    • This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

      – Ben Zotto
      Mar 24 at 2:34

















    This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

    – Ben Zotto
    Mar 24 at 2:34






    This is a good comprehensive answer. @noobie, if some of this seems over your head currently (ie, things like endianness and different sizeof(int)) then you may wish to ask followup questions about this. The short story here is that you can't really reliably shove the contents of your C structure into a file and then suck them back up. There may be cases where you could do so, but you shouldn't learn it from that direction; follow @Brendan's advice here for defining a binary format for your file and then processing it securely into your memory structures. This pattern will serve you well.

    – Ben Zotto
    Mar 24 at 2:34














    0














    Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.



    The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout one per line representing the integer in base 10 followed by a space and then the character".



    Let's assume that your int is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.



    Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf and fread. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.



    In your code you write



    while (!feof(fptr))


    This is always wrong. The only correct way for reading a file is:



    while (1) 
    // Read
    // Check
    // Use



    Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.



    So lets populate the above template. To check if fread succeeded you need to check if it returned the number of elements you asked for.



    while (1) 


    Of course you can pack this in the while condition, but I don't see a reason for that.



    Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.



    Here I assumed that you didn't learn structs yet. If this is not the case, you can work with them:



    struct widget 
    int i;
    char c;
    ;

    [...]

    while (1)
    struct widget w;
    // Read
    int ok1 = fread(&w.i, 4, 1, fptr);
    int ok2 = fread(&w.c, 1, 1, fptr);
    // Check
    if (ok1 != 1


    Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that



    fread(&w, 5, 1, fptr); // No! Don't do this


    will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget) returned 8.



    Disclaimer: I wrote the code directly on the browser and didn't check it!






    share|improve this answer



























      0














      Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.



      The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout one per line representing the integer in base 10 followed by a space and then the character".



      Let's assume that your int is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.



      Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf and fread. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.



      In your code you write



      while (!feof(fptr))


      This is always wrong. The only correct way for reading a file is:



      while (1) 
      // Read
      // Check
      // Use



      Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.



      So lets populate the above template. To check if fread succeeded you need to check if it returned the number of elements you asked for.



      while (1) 


      Of course you can pack this in the while condition, but I don't see a reason for that.



      Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.



      Here I assumed that you didn't learn structs yet. If this is not the case, you can work with them:



      struct widget 
      int i;
      char c;
      ;

      [...]

      while (1)
      struct widget w;
      // Read
      int ok1 = fread(&w.i, 4, 1, fptr);
      int ok2 = fread(&w.c, 1, 1, fptr);
      // Check
      if (ok1 != 1


      Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that



      fread(&w, 5, 1, fptr); // No! Don't do this


      will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget) returned 8.



      Disclaimer: I wrote the code directly on the browser and didn't check it!






      share|improve this answer

























        0












        0








        0







        Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.



        The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout one per line representing the integer in base 10 followed by a space and then the character".



        Let's assume that your int is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.



        Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf and fread. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.



        In your code you write



        while (!feof(fptr))


        This is always wrong. The only correct way for reading a file is:



        while (1) 
        // Read
        // Check
        // Use



        Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.



        So lets populate the above template. To check if fread succeeded you need to check if it returned the number of elements you asked for.



        while (1) 


        Of course you can pack this in the while condition, but I don't see a reason for that.



        Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.



        Here I assumed that you didn't learn structs yet. If this is not the case, you can work with them:



        struct widget 
        int i;
        char c;
        ;

        [...]

        while (1)
        struct widget w;
        // Read
        int ok1 = fread(&w.i, 4, 1, fptr);
        int ok2 = fread(&w.c, 1, 1, fptr);
        // Check
        if (ok1 != 1


        Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that



        fread(&w, 5, 1, fptr); // No! Don't do this


        will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget) returned 8.



        Disclaimer: I wrote the code directly on the browser and didn't check it!






        share|improve this answer













        Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.



        The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout one per line representing the integer in base 10 followed by a space and then the character".



        Let's assume that your int is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.



        Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf and fread. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.



        In your code you write



        while (!feof(fptr))


        This is always wrong. The only correct way for reading a file is:



        while (1) 
        // Read
        // Check
        // Use



        Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.



        So lets populate the above template. To check if fread succeeded you need to check if it returned the number of elements you asked for.



        while (1) 


        Of course you can pack this in the while condition, but I don't see a reason for that.



        Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.



        Here I assumed that you didn't learn structs yet. If this is not the case, you can work with them:



        struct widget 
        int i;
        char c;
        ;

        [...]

        while (1)
        struct widget w;
        // Read
        int ok1 = fread(&w.i, 4, 1, fptr);
        int ok2 = fread(&w.c, 1, 1, fptr);
        // Check
        if (ok1 != 1


        Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that



        fread(&w, 5, 1, fptr); // No! Don't do this


        will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget) returned 8.



        Disclaimer: I wrote the code directly on the browser and didn't check it!







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 24 at 19:10









        Costantino GranaCostantino Grana

        1,0381722




        1,0381722





















            -1














            I think you are getting a little too caught up in something that isn't really a fundamental problem. if you need to create a linked list from a file, you could use fscanf() or fread() or whatever you like to read a file into a buffer and manipulate that buffer as you wish. The same logic for parsing an array of ints (read in from a file) can be applied to parsing a buffer of strings from a binary file (you say binary file with sizeof(int), sizeof(char) consecutively so I'm going to assume you mean it can be read into a buffer)



            You say




            "If it was just a regular file with ints and no binary and no chars, I
            would have used fscanf to read the file and stored its contents into
            an array, and then I would have traversed through the array and made
            the nodes"




            you can traverse a string, or list of strings (however you decide to parse your buffer) using the same logic to make nodes. That's the beauty of a data structure, or struct if you will, in C.






            share|improve this answer

























            • Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

              – noobie
              Mar 24 at 0:33
















            -1














            I think you are getting a little too caught up in something that isn't really a fundamental problem. if you need to create a linked list from a file, you could use fscanf() or fread() or whatever you like to read a file into a buffer and manipulate that buffer as you wish. The same logic for parsing an array of ints (read in from a file) can be applied to parsing a buffer of strings from a binary file (you say binary file with sizeof(int), sizeof(char) consecutively so I'm going to assume you mean it can be read into a buffer)



            You say




            "If it was just a regular file with ints and no binary and no chars, I
            would have used fscanf to read the file and stored its contents into
            an array, and then I would have traversed through the array and made
            the nodes"




            you can traverse a string, or list of strings (however you decide to parse your buffer) using the same logic to make nodes. That's the beauty of a data structure, or struct if you will, in C.






            share|improve this answer

























            • Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

              – noobie
              Mar 24 at 0:33














            -1












            -1








            -1







            I think you are getting a little too caught up in something that isn't really a fundamental problem. if you need to create a linked list from a file, you could use fscanf() or fread() or whatever you like to read a file into a buffer and manipulate that buffer as you wish. The same logic for parsing an array of ints (read in from a file) can be applied to parsing a buffer of strings from a binary file (you say binary file with sizeof(int), sizeof(char) consecutively so I'm going to assume you mean it can be read into a buffer)



            You say




            "If it was just a regular file with ints and no binary and no chars, I
            would have used fscanf to read the file and stored its contents into
            an array, and then I would have traversed through the array and made
            the nodes"




            you can traverse a string, or list of strings (however you decide to parse your buffer) using the same logic to make nodes. That's the beauty of a data structure, or struct if you will, in C.






            share|improve this answer















            I think you are getting a little too caught up in something that isn't really a fundamental problem. if you need to create a linked list from a file, you could use fscanf() or fread() or whatever you like to read a file into a buffer and manipulate that buffer as you wish. The same logic for parsing an array of ints (read in from a file) can be applied to parsing a buffer of strings from a binary file (you say binary file with sizeof(int), sizeof(char) consecutively so I'm going to assume you mean it can be read into a buffer)



            You say




            "If it was just a regular file with ints and no binary and no chars, I
            would have used fscanf to read the file and stored its contents into
            an array, and then I would have traversed through the array and made
            the nodes"




            you can traverse a string, or list of strings (however you decide to parse your buffer) using the same logic to make nodes. That's the beauty of a data structure, or struct if you will, in C.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 31 at 7:59









            Rarblack

            3,19541229




            3,19541229










            answered Mar 23 at 6:16









            Dan LDan L

            64




            64












            • Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

              – noobie
              Mar 24 at 0:33


















            • Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

              – noobie
              Mar 24 at 0:33

















            Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

            – noobie
            Mar 24 at 0:33






            Thank you for your response, I really appreciate it. So would it be something like while(!feof(fptr)) fread(some_linked_list_pointer, sizeof(int)+sizeof(char), 1, fptr);

            – noobie
            Mar 24 at 0:33


















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55310632%2fhow-to-create-a-linked-list-from-a-binary-input-file-with-first-few-bytes-being%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현