0

How would one go about saving an integer array written as a c file into a JSON text file array file? Any help or links would be greatly appreciated.

Jefe
  • 9
  • 1
  • 3
  • JSON is just a way of formatting data. You can write a function or look for a library which handles some of the details for you. What have you tried so far? – Greg Nov 13 '15 at 04:24
  • 1
    e.g `int array[] = {1,2,3};` => `[ 1, 2, 3 ]` or `{ "array" : [ 1, 2, 3 ] }` – BLUEPIXY Nov 13 '15 at 04:26
  • I'm just trying to understand how I would start the process. I've learned how to use FILE* f = fopen (filename, "w" ); – Jefe Nov 13 '15 at 05:58
  • have to started coding with using json library? – Pawan Nov 13 '15 at 06:00
  • I'm just trying to understand how I would start the process. I've learned how to use FILE* f = fopen (filename, "w" ); create a header and use fwrite ( header, sizeof(int), 1, filename ); then use fwrite( ia->data, sizeof(int), ia->len, f ) to write the data to a binary xdr file. However I have only the faintest idea how to write to JSON. What are the sequence of commands? I understand the file has to start with a square bracket and each element has to be separated by a comma and end with a square bracket. I would greatly appreciate some direction around this. Thank you – Jefe Nov 13 '15 at 06:04
  • For simplicity it would be best if we could create a function to do it to learn how it is done. Many thanks – Jefe Nov 13 '15 at 06:07
  • If I just make a char array[ ] = { "[", "1", "2", "]" }; and want to copy it over to persistent memory do I need a header structure? – Jefe Nov 13 '15 at 07:22
  • `char array[ ] = { 1, 2 };` is already in memory. You just need to `printf ("{ \"array\" : [ %d, %d ] }\n", array[0], array[1]);` Let me know what you want your output format to look like and I'll help with the function. – David C. Rankin Nov 13 '15 at 07:29

1 Answers1

2

Continuing from the comment. When you declare an array, such as:

int array[] = { 1, 2, 3, 4, 5, 6, 7, 8 };

That array exists in memory and you can pass the array to your output function that will write the array to a file in the format you specify. When you pass an array to a function you also need to pass the size of the array. An array variable passed as a parameter to a function is converted to a pointer. Following the conversion, there is no way to determine the size of the original array in the function. (in a general sense)

All you need your function to do is open a file for writing, write any text needed before you write the array elements, write the array elements, then write any closing formatting needed. A quick example to help you along could be something like the following where the array values are written to the filename provided on the command line (or "jsonout.txt" default):

#include <stdio.h>

void jsonout (char *fname, int *a, size_t sz);

int main (int argc, char **argv) {

    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    size_t size = sizeof array/sizeof *array;
    char *file = argc > 1 ? argv[1] : "jsonout.txt";

    jsonout (file, array, size);

    return 0;
}

/* output function to write "{ "array" : [ v1, v2, .... ] }" to 'fname'
 * where v1, v2, ... are the values in the array 'a' of size 'sz'
 */
void jsonout (char *fname, int *a, size_t sz)
{
    size_t i;
    FILE *fp = fopen (fname, "w+"); /* open file for writing */

    if (!fp) {  /* validate file is open, or throw error */
        fprintf (stderr, "jsonout() error: file open failed '%s'.\n", 
                fname);
        return;
    }

    fprintf (fp, "{ \"array\" : [");    /* print header to file */

    for (i = 0; i < sz; i++)            /* print each integer   */
        if (i == 0)
            fprintf (fp, " %d", a[i]);
        else
            fprintf (fp, ", %d", a[i]);

    fprintf (fp, " ] }\n");     /* print closing tag */

    fclose (fp);
}

Output File

$ cat jsonout.txt
{ "array" : [ 1, 2, 3, 4, 5, 6, 7, 8 ] }

Let me know if you need further help.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • I see the FILE* fp, fprintf and f close sequence that is needed. And many thanks for that. May I ask if you have a variable number array. How might it get changed to string and concatenated with the opening and closing brackets and appropriate commas? Thanks very much. – Jefe Nov 14 '15 at 07:20
  • This is really beginner but now that I have figured out how to alternate between a int and a comma, how do I cut off the last comma and add square brackets around the whole thing. int main () { char name[] = "foo" "bar"; int i; char comma[] = ","; for ( i=0; i – Jefe Nov 14 '15 at 07:51
  • If you look carefully at the code I posted in the function `jsonout` you see I print `fprintf (fp, "{ \"array\" : [");` to print `{ "array" : [`. I then enter a loop to print each element of the array. `for (i = 0; i < sz; i++)` for the first element (`i=0`) I print `" %d"` (without a comma). For all remaining elements I print `", %d"` (placing a comma behind the last number printed *before the current*). When the loop completes I print the closing `] }`. This gives the complete `{ "array" : [ 1, 2, 3, 4, 5, 6, 7, 8 ] }` Let me know if you have further questions. – David C. Rankin Nov 14 '15 at 09:05
  • This is amazing. Thx! – Jefe Nov 18 '15 at 19:22
  • Using $ cat myJSON.txt command I see that the file has successfully written to external memory. I have also added the length of the array to the head of the text file. So the question is what options do I have to check if the char array element is a "[" or "," ? Between those two characters will be my length that I can use to convert the rest of the numbers in the text file to an integer array in c... Cheers and thanks for your skill and time. – Jefe Nov 19 '15 at 07:19
  • Ok, shouldn't be hard, but I'm confused where you have added the length and whether it is something that just needs to be printed or if you need to read the value and get the number between `"["` and `","`? Let me know and I'm happy to help. If you have `char carray = "stuff [25, stuff";` and you want to find the `[`, you can simply do `char *p = strchr (carray, '[');` which will give you a pointer to `[` in the string. (then just do `num = (int)strtol(p + 1, NULL, 10);`, or something similar to convert the `25` to a number. – David C. Rankin Nov 19 '15 at 07:28
  • Instead of adding a header length in the JSON array, how do I scan the elements to get the number of elements? What differentiates the numbers in a text based array from the commas and square brackets? – Jefe Nov 19 '15 at 19:51
  • Still a bit confused. If you look at the `size_t size` declaration, I use `sizeof` to determine the number of elements in the array. That is all you can do with a statically declared/initialized array (in the same scope) -- unless you include a *sentinel* character marking the end of the array. Where I am confused by your comment, is it appears you are wanting to read data from a data file and scan for the number of inputs. That is easy to do, but I need an example of what you want to read if that is the case. – David C. Rankin Nov 20 '15 at 03:35
  • We have successfully stored the int array as a JSON file. Now I want to get that file back from the JSON text file and make it the exact integer array we started with. My apologies if the solution is already in the code. – Jefe Nov 20 '15 at 23:52
  • so this line of the code : size_t size = sizeof array/sizeof *array; actually stores the number of elements in the array? – Jefe Nov 21 '15 at 00:04
  • I don't know how to differentiate a JSON array like [ 1, 2, 3, 4, 5 ] that is all text to the integers 1 2 3 4 5 and store those integers in an int array. – Jefe Nov 21 '15 at 00:12
  • Oh! No magic. That depends on the storage type for the numbers in your program. For instance, if you have an array of integers (e.g. `int array = {1,2,3,4,5};`), then obviously `1,2,3,4,5` are integer values. However, if you read a string of numbers from a file `"1,2,3,4,5"`, then you have character values `1,2,3,4,5` that must be separated and converted to numbers (e.g. with `strtol` or `sscanf`) Because a string holds characters (e.g. *ASCII* values, where the character value for `'1'` is 49, for `'2'` 50, etc.) So you must convert character values to numeric values. – David C. Rankin Nov 21 '15 at 08:40
  • Hopefully by crashing around with this JSON file I'll be able to learn how the I/O works for a website that returns JSON dictionary: last - last BTC price high - last 24 hours etc.... The man page for sscanf is convoluted. Does the function differentiate between text numbers and commas? – Jefe Nov 22 '15 at 02:25
  • Yes, and you can either use `sscanf` (which will convert, but as you find, the *format-specifier* can be challenging) or simply use `strtol` and 2 pointers to step down the string that way. The proper approach is to read a line at a time from the website, and then either by `sscanf` or conversion with `strtol` and pointers. – David C. Rankin Nov 22 '15 at 03:57