⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spice.cpp

📁 这是一个根据网表建立矩阵的程序
💻 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 + -