📄 spice.cpp
字号:
// test.cpp : Defines the entry point for the console application.
//
#include "string.h"
#include "stdio.h"
#include "malloc.h"
#include "conio.h"
#include "stdlib.h"
#define VOLTAGE 0
#define RESISTANT 1
#define CAPACITY 2
#define INDUCTANTCE 3
void getline(char *str);
void scanblock();
struct node *splitstr(char *str);
struct component *subop(char *str,struct node *nd);
struct component *inductance(char *up,struct node *nd);
struct component *resistant(char *up,struct node *nd);
struct component *voltage(char *up,struct node *nd);
struct component *capacity(char *up,struct node *nd);
int getnode(char *str,struct node *nd);
struct component *subproc(struct node *nd,int num);
struct component *process();
int find(struct node *nd,char *str);
void genevector(component *com);
struct point getpoint(char *str,struct component *com);
struct kblock *mutual(char *up,struct component *com);
int flag=0;
FILE *of,*sf;
FILE *savef;
struct sbname
{
char nm[20];
long bpos,epos;
long len;
};
int sblen=0;
struct sbname sbn[50];
struct point
{
int left;
int right;
};
struct kblock
{
char name[20];
struct point leftL;
struct point rightL;
double val;
struct kblock *next;
};
struct kblock *kb,*backkb;
int index=1;
int lindex=0;
int vindex=0;
struct Iinfo
{
struct point p;
int num;
struct Iinfo *next;
};
struct component //记录元件的信息,包括左节点,右节点,类型,value
{
int lnode,rnode;
char name[20];
char type;
double val;
struct component *next;
};
struct node
{
char name[20];
int val;
struct node *next;
};
int main(int argc, char* argv[])
{
struct component *allcom,*backcom;
if(argc<2)
{
printf("usage: cmd the path of the file!\n");
printf("such: spice d:\\abc.txt\n");
return 0;
}
if((of=fopen(argv[1],"r"))==NULL)
{
printf("fail to open the file!\n");
return -1;
}
if((sf=fopen("D:\\res.txt","w+"))==NULL)
{
printf("fail to create the file!\n");
return -1;
}
if((savef=fopen("D:\\out.txt","w+"))==NULL)
{
printf("fail to create the file!\n");
return -1;
}
scanblock();
flag=0;
backkb=kb=(struct kblock *)malloc(sizeof(struct kblock));
kb->next=NULL;
backcom=allcom=process();
/*while(allcom!=NULL)
{
fprintf(sf,"name=%-10s lnode=%-4d rnode=%-4d type=%-4d value=%-20.5e\n",allcom->name,allcom->lnode,allcom->rnode,allcom->type,allcom->val);
allcom=allcom->next;
}*/
genevector(backcom);
fclose(of);
fclose(sf);
fclose(savef);
return 0;
}
void scanblock()
{
char str[500];
char *up;
char midsb[20];
char midsbname[20];
long cur;
while(flag==0)
{
cur=ftell(of);
getline(str);
up=strupr(str);
memset(midsb,0,20);
memset(midsbname,0,20);
sscanf(up,"%s %s",midsb,midsbname);
if(strcmp(midsb,".SUBCKT")==0)
{
strcpy(sbn[sblen].nm,midsbname);
sbn[sblen].bpos=cur;
cur=0;
while(flag==0)
{
getline(str);
cur++;
up=strupr(str);
memset(midsb,0,20);
sscanf(up,"%s",midsb);
if(strcmp(midsb,".ENDS")==0)
{
sbn[sblen].len=cur;
sbn[sblen].epos=ftell(of);
break;
}
}
sblen++;
}
}
fseek(of,0,SEEK_SET);
}
struct node *splitstr(char *str)
{
int i,k=0,len;
char midstr[20];
struct node *mid,*head,*p;
head=(struct node *)malloc(sizeof(struct node));
mid=head;
len=strlen(str);
memset(midstr,0,20);
for(i=0;i<len;i++)
{
if(str[i]!=' ')
{
midstr[k]=str[i];
k++;
}
else
{
while(str[i]==' ') i++;
i-=1;
p=(struct node *)malloc(sizeof(struct node));
strcpy(p->name,midstr);
p->next=NULL;
mid->next=p;
mid=p;
memset(midstr,0,20);
k=0;
}
}
p=(struct node *)malloc(sizeof(struct node));
strcpy(p->name,midstr);
p->next=NULL;
mid->next=p;
mid=p;
head=head->next;
return head;
}
void getline(char *str)
{
char ch;
int k;
memset(str,0,500);
int i=0;
k=fscanf(of,"%c",&ch);
while(ch!='\n'&&k!=EOF)
{
str[i]=ch;
i++;
k=fscanf(of,"%c",&ch);
}
if(k==EOF)
flag=1;
/*char *ch;
memset(str,0,500);
ch=fgets(str,500,of);
if(ch==NULL)
flag=1;*/
}
struct component *subop(char *str,struct node *nd)
{
struct node *hcom,*mid,*p;
struct component *res;
struct node *subnd,*subp,*submid;
long prepos;
prepos=ftell(of);
submid=subnd=(struct node *)malloc(sizeof(struct node));
int i=0;
int kk;
char midstr[500];
hcom=p=splitstr(str);
while(p!=NULL)
{
mid=p;
p=p->next;
}
while(strcmp(mid->name,sbn[i].nm)!=0&&i<sblen)
{
i++;
}
fseek(of,sbn[i].bpos,SEEK_SET);
getline(midstr);
p=splitstr(midstr);
p=p->next;p=p->next;
hcom=hcom->next;
while(p!=NULL)
{
kk=getnode(hcom->name,nd);
subp=(struct node *)malloc(sizeof(struct node));
strcpy(subp->name,strupr(p->name));
subp->val=kk;
subp->next=NULL;
submid->next=subp;
submid=subp;
p=p->next;
hcom=hcom->next;
}
subnd=subnd->next;
submid=subnd;
while(submid!=NULL)
submid=submid->next;
res=subproc(subnd,sbn[i].len);
fseek(of,prepos,SEEK_SET);
return res;
}
struct component *process()
{
struct component *res,*p,*mid,*kmid;
char str[500];
char mk[20];
struct kblock *midkk;
char *up;
struct node *nd;
nd=(struct node *)malloc(sizeof(struct node));
nd->next=NULL;
strcpy(nd->name,"");
nd->val=-1;
mid=res=(struct component *)malloc(sizeof(struct component));
while(flag==0)
{
getline(str);
up=strupr(str);
if(strlen(str)>0)
switch(up[0])
{
case '*':
break;
case 'K':
kmid=res;
midkk=mutual(up,kmid);
backkb->next=midkk;
backkb=midkk;
break;
case 'V':
p=voltage(up,nd);
mid->next=p;
mid=p;
break;
case 'C':
p=capacity(up,nd);
mid->next=p;
mid=p;
break;
case 'R':
p=resistant(up,nd);
mid->next=p;
mid=p;
break;
case 'L':
p=inductance(up,nd);
mid->next=p;
mid=p;
break;
case 'X':
p=subop(up,nd);
mid->next=p;
mid=p;
while(mid->next!=NULL)
mid=mid->next;
break;
default: break;
}
sscanf(up,"%s",mk);
if(strcmp(mk,".SUBCKT")==0)
{
getline(str);
up=strupr(str);
sscanf(up,"%s",mk);
while(strcmp(mk,".ENDS")!=0)
{
getline(str);
up=strupr(str);
sscanf(up,"%s",mk);
}
}
}
res=res->next;
return res;
}
struct component *subproc(struct node *nd,int num)
{
struct component *res,*subp,*submid,*kmid;
char str[500];
struct kblock *midkk;
char *up;
int i=1;
res=(struct component *)malloc(sizeof(struct component));
submid=res;
while(i<num)
{
getline(str);
up=strupr(str);
switch(up[0])
{
case '*':
break;
case 'K':
kmid=res;
midkk=mutual(up,kmid);
backkb->next=midkk;
backkb=midkk;
break;
case 'V':
subp=voltage(up,nd);
submid->next=subp;
submid=subp;
break;
case 'C':
subp=capacity(up,nd);
submid->next=subp;
submid=subp;
break;
case 'R':
subp=resistant(up,nd);
submid->next=subp;
submid=subp;
break;
case 'L':
subp=inductance(up,nd);
submid->next=subp;
submid=subp;
break;
case 'X':
subp=subop(up,nd);
submid->next=subp;
submid=subp;
while(submid->next!=NULL)
submid=submid->next;
break;
default: break;
}
i++;
}
res=res->next;submid=res;
return res;
}
struct component *voltage(char *up,struct node *nd)
{
char ss[5][20];
struct component *newcom;
sscanf(up,"%s %s %s %s",ss[0],ss[1],ss[2],ss[3]);
if(strcmp(ss[3],"AC")==0||strcmp(ss[3],"ac")==0)
sscanf(up,"%s %s %s %s %s",ss[0],ss[1],ss[2],ss[3],ss[4]);
newcom=(struct component *)malloc(sizeof(struct component));
strcpy(newcom->name,ss[0]);
newcom->lnode=getnode(ss[1],nd);
newcom->rnode=getnode(ss[2],nd);
newcom->type=VOLTAGE;
if(strcmp(ss[3],"AC")==0||strcmp(ss[3],"ac")==0)
newcom->val=atof(ss[4]);
else
newcom->val=atof(ss[3]);
newcom->next=NULL;
vindex++;
return newcom;
}
struct component *capacity(char *up,struct node *nd)
{
char ss[4][20];
struct component *newcom;
sscanf(up,"%s %s %s %s",ss[0],ss[1],ss[2],ss[3]);
newcom=(struct component *)malloc(sizeof(struct component));
strcpy(newcom->name,ss[0]);
newcom->lnode=getnode(ss[1],nd);
newcom->rnode=getnode(ss[2],nd);
newcom->type=CAPACITY;
newcom->val=atof(ss[3]);
newcom->next=NULL;
return newcom;
}
struct kblock *mutual(char *up,struct component *com)
{
struct kblock *newkb;
char ss[4][20];
sscanf(up,"%s %s %s %s",ss[0],ss[1],ss[2],ss[3]);
newkb=(struct kblock *)malloc(sizeof(struct kblock));
strcpy(newkb->name,ss[0]);
newkb->leftL=getpoint(ss[1],com);
newkb->rightL=getpoint(ss[2],com);
newkb->val=atof(ss[3]);
newkb->next=NULL;
return newkb;
}
struct point getpoint(char *str,struct component *com)
{
struct point newp;
while(com!=NULL)
{
if(strcmp(str,com->name)==0)
{
newp.left=com->lnode;
newp.right=com->rnode;
break;
}
com=com->next;
}
return newp;
}
struct component *resistant(char *up,struct node *nd)
{
char ss[4][20];
struct component *newcom;
sscanf(up,"%s %s %s %s",ss[0],ss[1],ss[2],ss[3]);
newcom=(struct component *)malloc(sizeof(struct component));
strcpy(newcom->name,ss[0]);
newcom->lnode=getnode(ss[1],nd);
newcom->rnode=getnode(ss[2],nd);
newcom->type=RESISTANT;
newcom->val=atof(ss[3]);
newcom->next=NULL;
return newcom;
}
struct component *inductance(char *up,struct node *nd)
{
char ss[4][20];
struct component *newcom;
sscanf(up,"%s %s %s %s",ss[0],ss[1],ss[2],ss[3]);
newcom=(struct component *)malloc(sizeof(struct component));
strcpy(newcom->name,ss[0]);
newcom->lnode=getnode(ss[1],nd);
newcom->rnode=getnode(ss[2],nd);
newcom->type=INDUCTANTCE;
newcom->val=atof(ss[3]);
newcom->next=NULL;
lindex++;
return newcom;
}
int getnode(char *str,struct node *nd)
{
struct node *p,*mid;
if(strcmp(str,"0")==0)
return 0;
int fres;
fres=find(nd,str);
if(fres==-1)
{
p=nd;
while(p->next!=NULL)
p=p->next;
mid=(struct node *)malloc(sizeof(struct node));
strcpy(mid->name,str);
mid->next=NULL;
mid->val=index++;
p->next=mid;
return index-1;
}
else
return fres;
}
int find(struct node *nd,char *str)
{
struct node *p;
p=nd;
while(p!=NULL)
{
if(strcmp(p->name,str)==0)
break;
p=p->next;
}
if(p!=NULL)
return p->val;
else
return -1;
}
void genevector(component *com)
{
int len;
int Inum=index-1;
len=index+lindex+vindex-1;
int i,j;
struct Iinfo *curinfo,*backcur,*newcur;
double **C;
double **G;
curinfo=backcur=(struct Iinfo *)malloc(sizeof(struct Iinfo));
curinfo->next=NULL;
C=(double **)malloc(sizeof(double)*len);
G=(double **)malloc(sizeof(double)*len);
for(i=0;i<len;i++)
{
C[i]=(double *)malloc(sizeof(double)*len);
G[i]=(double *)malloc(sizeof(double)*len);
}
for(i=0;i<len;i++)
{
memset(C[i],0,sizeof(double)*len);
memset(G[i],0,sizeof(double)*len);
}
while(com!=NULL)
{
switch(com->name[0])
{
case 'V':
if(com->lnode!=0)
{
if(com->lnode<com->rnode)
{
G[com->lnode][Inum]=-1;
G[com->rnode][Inum]=1;
G[Inum][com->lnode]=1;
G[Inum][com->rnode]=-1;
}
else if(com->rnode!=0)
{
G[com->lnode][Inum]=1;
G[com->rnode][Inum]=-1;
G[Inum][com->lnode]=-1;
G[Inum][com->rnode]=1;
}
else
{
G[com->lnode][Inum]=1;
G[Inum][com->lnode]=1;
}
}
else
{
G[com->rnode][Inum]=1;
G[Inum][com->rnode]=1;
}
Inum++;
break;
case 'R':
if(com->lnode!=0)
{
G[com->lnode-1][com->lnode-1]+=1/com->val;
if(com->rnode!=0)
{
G[com->rnode-1][com->rnode-1]+=1/com->val;
G[com->lnode-1][com->rnode-1]-=1/com->val;
G[com->rnode-1][com->lnode-1]-=1/com->val;
}
else if(com->rnode!=0)
G[com->rnode-1][com->rnode-1]+=1/com->val;
}
break;
case 'C':
if(com->lnode!=0)
{
C[com->lnode-1][com->lnode-1]+=com->val;
if(com->rnode!=0)
{
C[com->rnode-1][com->rnode-1]+=com->val;
C[com->lnode-1][com->rnode-1]-=com->val;
C[com->rnode-1][com->lnode-1]-=com->val;
}
}
else if(com->rnode!=0)
C[com->rnode-1][com->rnode-1]+=com->val;
break;
case 'L':
if(com->lnode!=0)
{
if(com->lnode<com->rnode)
{
G[com->lnode][Inum]=1;
G[com->rnode][Inum]=-1;
G[Inum][com->lnode]=-1;
G[Inum][com->rnode]=1;
}
else if(com->rnode!=0)
{
G[com->lnode][Inum]=-1;
G[com->rnode][Inum]=1;
G[Inum][com->lnode]=1;
G[Inum][com->rnode]=-1;
}
else
{
G[com->lnode][Inum]=-1;
G[Inum][com->lnode]=-1;
}
}
else
{
G[com->rnode][Inum]=-1;
G[Inum][com->rnode]=-1;
}
C[Inum][Inum]-=com->val;
newcur=(struct Iinfo *)malloc(sizeof(struct Iinfo));
newcur->p.left=com->lnode;
newcur->p.right=com->rnode;
newcur->num=Inum;
newcur->next=NULL;
backcur->next=newcur;
backcur=newcur;
Inum++;
break;
default :
break;
}
com=com->next;
}
if(kb!=NULL)
{
kb=kb->next;
int tp1,tp2;
while(kb!=NULL)
{
backcur=curinfo->next;
while(backcur!=NULL)
{
if(backcur->p.left==kb->leftL.left&&backcur->p.right==kb->leftL.right)
tp1=backcur->num;
backcur=backcur->next;
}
backcur=curinfo->next;
while(backcur!=NULL)
{
if(backcur->p.left==kb->rightL.left&&backcur->p.right==kb->rightL.right)
tp2=backcur->num;
backcur=backcur->next;
}
C[tp1][tp2]-=kb->val;
C[tp2][tp1]-=kb->val;
kb=kb->next;
}
}
fprintf(savef,"\n** Matrix C (Size: %d x %d) **\n",len,len);
for(i=0;i<len;i++)
{
for(j=0;j<len;j++)
fprintf(savef,"%15.4e",C[i][j]);
fprintf(savef,"\n");
}
fprintf(savef,"\n** Matrix G (Size: %d x %d) **\n",len,len);
for(i=0;i<len;i++)
{
for(j=0;j<len;j++)
fprintf(savef,"%15.4e",G[i][j]);
fprintf(savef,"\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -