是什么让这个保存的数组与加载的数组不同?

时间:2016-08-08 05:31:04

标签: c arrays json

我有这个函数将整个数组ia保存到一个名为'filename'的文件中,采用JSON文本文件数组文件格式:

int intarr_save_json( intarr_t* ia, const char* filename )
{
    if(ia==NULL)
    {
        return 1;
    }
    int *arr=ia->data;
    int n=ia->len;
    int i;
    FILE *p;
    p=fopen(filename,"w");
    if(p!=NULL)
    {
        fprintf(p,"[\n");
        for(i=0;i<n;i++)
        {
            if(i!=n-1)  
            {
                fprintf(p," %d,\n",arr[i]);
            }
            else
            {
                fprintf(p," %d\n",arr[i]);
            }
        }
        fprintf(p,"]");
        fclose(p);
        return 0;
    }
    return 1;
}

这个函数从名为'filename'的文件加载一个新数组,就是这样  以前使用intarr_save()保存。

intarr_t* intarr_load_json( const char* filename )
{
    FILE* f = fopen(filename, "r");
    if (f == NULL) return NULL;

    intarr_t* loaded = intarr_create(0);

    int value;
    //Get rid of [
    fscanf(f, "%c ", &value);

    while (fscanf(f, "%d, ", &value)) {
        if (value == ']') break;
        intarr_push(loaded, value);
    }


    fclose(f);
    return loaded;
}

这一切看起来都不错,但由于某种原因,加载的数组的长度与保存的数组的长度不同。可能导致这种情况的原因是什么?

编辑:现在我的功能就像这样

int intarr_save_json( intarr_t* ia, const char* filename )
{
    if(ia == NULL)
    {
        return 1;
    }
    int *arr=ia->data;
    int n=ia->len;
    int i;
    FILE *p;
    p=fopen(filename,"w");
    if(p!=NULL)
    {
        fprintf(p,"[\n");
        for(i=0;i<n;i++)
        {
            if(i!=n-1)  
            {
                fprintf(p," %d,\n",arr[i]);
            }
            else
            {
                fprintf(p," %d\n",arr[i]);
            }
        }
        fprintf(p,"]");
        fclose(p);
        return 0;
    }
    return 1;
}

and
intarr_t* intarr_load_json( const char* filename )
{
    FILE* f = fopen(filename, "r");
    if (f == NULL)
    {
        return NULL;
    }

    intarr_t* loaded = intarr_create(0);

    int value;


    char line[100];
    while ( fgets(line, 100, f) )
    {
        if ( line[0] == ']' )
           {
            break;
           }

        if ( sscanf(line, "%d", &value) != 1 )
            {
              break;
            }

    // Use the number
    intarr_push(loaded, value);
    }

    fclose(f);
    return loaded;
}

但是现在加载总是返回一个空指针。可能导致这种情况的原因是什么?

2 个答案:

答案 0 :(得分:1)

中使用的逻辑
while (fscanf(f, "%d, ", &value)) {
    if (value == ']') break;

有缺陷。

文件的最后两行是

<some number>
]

fscanf的调用将在该行失败。因此,您最终会读到比写入文件少一个的数字。

我建议稍微改变策略。

// Read the contents of the file line by line
// Process each line.
char line[100];
while ( fgets(line, 100, f) )
{
    if ( line[0] == ']' )
    {
       break;
    }

    if ( sscanf(line, "%d", &value) != 1 )
    {
       break;
    }

    // Use the number
    intarr_push(loaded, value);
}

答案 1 :(得分:0)

您必须在每个整数后读取一个非空格字符,并在它是右括号']'而不是逗号','时停止读取。  所以你的阅读循环应该是:

do {
    char sep[2];
    int cr = fscanf(f, "%d%1s", &value, sep)) { /* read one value and the separator */
    if (cr != 2) {
        /* signal the error, exit, ... */
    }
    intarr_push(loaded, value); /* always push the value */
} while (sep[0]== ']') break;    /* loop until the separator if a ] */