我正在尝试构建一个空终止的stucts数组
以下是代码:lzdata.c
#include <stdlib.h>
#include <stdio.h>
#include "nist.h"
int main(int argc,char *argv[])
{
nist_t *nist; /* NIST data */
nist=readnist();
}
文件nist.c
#include <stdlib.h>
#include <stdio.h>
#include "nist.h"
nist_t *readnist()
{
nist_t *nist; /* NIST data */
char line[50];
int len=50;
int i=0;
nist=(nist_t*)malloc(sizeof(nist_t));
while(fgets(line,len,stdin))
{
nist=(nist_t*)realloc(nist,sizeof(nist_t)*(i+1));
sscanf(line,"%s %s %f %lf",nist[i].config,nist[i].term,&(nist[i].j),&(nist[i].level));
++i;
}
nist=(nist_t*)realloc(nist,sizeof(nist_t)*(i+1));
nist[i]=(nist_t)NULL;
return nist;
}
标题文件nist.h
:
#ifndef NIST_H
#define NIST_H
typedef struct
{
char config[3];
char term[4];
float j;
double level;
} nist_t;
nist_t *readnist();
#endif
数据文件,将通过STDIN提供给应用程序:
2s ¹S 0.0 0.000000
2p ³P° 1.0 142075.333333
2p ¹P° 0.0 271687.000000
2p ³P 1.0 367448.333333
2p ¹D 0.0 405100.000000
2p ¹S 0.0 499633.000000
3s ³S 0.0 1532450.000000
3s ¹S 0.0 1558080.000000
3p ¹P° 0.0 1593600.000000
3p ³P° 1.0 1597500.000000
3d ³D 1.0 1631176.666667
3d ¹D 0.0 1654580.000000
3s ³P° 1.0 1711763.333333
3s ¹P° 0.0 1743040.000000
3p ³D 1.0 1756970.000000
3p ³S 0.0 1770380.000000
3p ³P 0.5 1779340.000000
3p ¹D 0.0 1795870.000000
3d ³P° 1.0 1816053.333333
3d ¹F° 0.0 1834690.000000
3d ¹P° 0.0 1841560.000000
...
...
编译时:
$ cc -O2 -o lzdata lzdata.c nist.c
nist.c: In function ‘readnist’:
nist.c:24:2: error: conversion to non-scalar type requested
我尝试将行nist[i]=(nist_t)NULL;
更改为nist[i]=(nist_t*)NULL;
,我得到了:
$ cc -O2 -o lzdata lzdata.c nist.c
nist.c: In function ‘readnist’:
nist.c:24:9: error: incompatible types when assigning to type ‘nist_t’ from type ‘struct nist_t *’
我尝试将行nist[i]=(nist_t)NULL;
更改为nist[i]=NULL;
,我得到了:
$ cc -O2 -o lzdata lzdata.c nist.c
nist.c: In function ‘readnist’:
nist.c:24:9: error: incompatible types when assigning to type ‘nist_t’ from type ‘void *’
不同的数据文件中可能有不同数量的行。我正在寻求构建一个以NULL结尾的nist_t
数据数组,所以我可以处理它直到我到达NULL元素。这可能吗?
答案 0 :(得分:2)
对于编译器,宏NULL
似乎被定义为((void *) 0)
,这是一个指向零的通用指针。由于nist[i]
(对于i
的任何有效值)而不是指针,您会收到错误。
解决此问题的最佳方法可能是将指针从main
通过引用传递给函数并使用它,然后返回大小。或者通过引用传递整数,并将其设置为大小。
还有另一个解决方案,那就是有一个指针数组。然后,您需要分别分配每个nist_t
结构,并将它们全部释放。然后,您可以使用NULL
来指示数组的结尾。这实际上是argv
的工作原理,它由NULL
指针终止(因此argv[argc]
始终等于NULL
)。
答案 1 :(得分:1)
你有一系列结构。 NULL
是一个null 指针常量。结构类型没有空值 - 除非您自己定义一些不同的值。
例如,您可以修改nist_t
类型,使其具有指示整个值是否有效的成员:
#include <stdbool.h>
typedef struct
{
bool is_valid;
char config[3];
char term[4];
float j;
double level;
} nist_t;
然后使用nist_t
元素标记数组的结尾,is_valid
设置为false
。或者也许你可以为其中一个成员使用一些无效值。
这意味着您需要小心处理您编写的任何处理这些结构的代码,以确保is_valid
被正确初始化,并且您不会尝试将其他成员值用于{{ 1}}是is_valid
。
或者你可以构建一个数组,如果false
指针,将终止元素设置为空指针类型,为其分配nist_t*
。
但是,跟踪NULL
对象数组中有效元素的数量可能更简单。
nist_t
定义的特定方式在这里不是很重要。真正重要的是它是一个空指针常量。将NULL
分配给指针对象使其成为空指针;将它分配给任何非指针都是无效的(尽管有些情况下编译器可能会让你侥幸逃脱)。
答案 2 :(得分:0)
这有效:
nist_t *readnist()
{
nist_t *nist=NULL; /* NIST data */
char line[50]; /* A single line of NIST data */
char config[10]; /* nl quantum numbers */
char term[10]; /* Rotational term */
float j;
double level; /* energy level */
int len=50; /* default length of string */
int i=0; /* counter/index variable */
int n; /* principal quantum number */
char l; /* azimuthal quantum number */
int en=0; /* error number */
while(fgets(line,len,stdin))
{
(void)sscanf(line,"%s\t%s\t%f\t%lf",config,term,&j,&level);
if(NULL==(nist=(nist_t*)realloc(nist,sizeof(nist_t)*(i+1))))
{
en=errno;
fprintf(stderr,"Error %d: memory allocation failure\n",en);
fprintf(stderr,"File:\t\t%s\n",__FILE__);
fprintf(stderr,"Function:\t%s\n",__FUNCTION__);
fprintf(stderr,"Line:\t\t%d\n",__LINE__-6);
exit(en);
};
nist[i].config=(char*)malloc(sizeof(char)*(strlen(config)+1));
nist[i].term=(char*)malloc(sizeof(char)*(strlen(term)+1));
strcpy(nist[i].config,config);
sscanf(config,"%d%c",&n,&l);
nist[i].n=n;
strcpy(nist[i].term,term);
nist[i].j=j;
nist[i].level=level;
++i;
}
nist=(nist_t*)realloc(nist,sizeof(nist_t)*(i+1));
nist[i].config=NULL;
nist[i].term=NULL;
nist[i].j=0.0;
nist[i].level=0.0;
return nist;
}
以下是我用来测试它的例程:
nist_t *prtnist(nist_t *nist)
{
int i=0;
while((NULL!=nist[i].config) && (NULL!=nist[i].term))
{
fprintf(stderr,"%s\t%d\t%s\t%4.1f\t%14.8e\n",nist[i].config,nist[i].n,nist[i].term,nist[i].j,nist[i].level);
++i;
}
return nist;
}
现在,我必须想办法从config
字符串中获取方位角量子数。