See
circuit.h
circuit.cpp
These files contain an implementation of simple circuits. There is
a circuit class that contains a list of circuit
elements (devices) and a list of connections (nodes). The class device is an abstract class. There two concrete
classes based on device: resistor
and current source.
circuit.h#pragma once
#include <assert.h>
#include <string>
using namespace std;
class device {
public:
string name;
string *nodes;
int *ndx;
double x, y;
double orientation;
double value;
device() { };
device(int n);
virtual ~device();
virtual int getNodeCount() const = 0;
virtual string getType() const = 0;
virtual string getCode() const = 0;
void parse(string tok[], int ntokens);
void parse_value(string tok);
};
class Resistor: public device {
public:
Resistor(): device(2) { }
int getNodeCount() const { return 2; }
string getType() const { return "resistor"; }
string getCode() const { return "R"; }
};
class CurrentSource: public device {
public:
CurrentSource(): device(2) { }
int getNodeCount() const { return 2; }
string getType()const { return "current source"; }
string getCode() const { return "I"; }
};
class circuit {
public:
string *nodes;
int ncount;
device **element;
int ndevices;
circuit() {create(8,16); }
~circuit();
void create(int node_count, int device_count);
void read(FILE *in);
void list_nodes();
void list_devices();
void build_node_list();
int add_node(string str);
};
circuit.cpp//#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include "circuit.h"
using namespace std;
char *strtrm(char *str, char delimiter);
char *strtoken(char* &inp, char delimiter);
device::device(int n)
{
nodes = new string[n];
ndx = new int[n];
value = 0.0;
x = y = orientation = 0.0;
}
device::~device()
{
if (nodes) delete [] nodes;
nodes = 0;
}
const string suffix("afpnumkKMGT");
const double scales[] = {1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e3, 1e3, 1e6, 1e9, 1e12};
void device::parse_value(string tok)
{
char c=0;
sscanf_s(tok.c_str(),"%lg%c",&value,&c);
if (c) {
size_t pos = suffix.find(c);
if (pos>=0) value *= scales[pos];
}
}
void device::parse(string tok[], int ntokens)
{
int n = getNodeCount();
assert(ntokens>n+2);
name = tok[1];
for (int j=0; j<n; j++) {
nodes[j] = tok[2+j];
}
n += 2;
parse_value(tok[n++]);
if (ntokens<n+1) return;
if (tok[n][0]=='[') {
char c=0;
sscanf_s(tok[n++].c_str()+1,"%lg",&x);
sscanf_s(tok[n++].c_str(),"%lg%c",&y,&c);
if (c==']') orientation = 0.0;
else sscanf_s(tok[n++].c_str(),"%lg",&orientation);
}
}
void circuit::create(int node_count, int device_count)
{
nodes = new string[node_count];
element = new device *[device_count];
ncount = ndevices = 0;
}
circuit::~circuit()
{
if (nodes) delete [] nodes;
for (int i=0; i<ndevices; i++) delete element[i];
if (element) delete [] element;
}
void circuit::read(FILE *in)
{
char buf[512];
char *inp, *token;
bool done = false;
int lines = 0;
add_node(string("0"));
while (!done) {
fgets(buf,511,in);
if (feof(in)) return;
lines++;
strtrm(buf,'\n'); // terminate at newline character
printf("%2d: %s\n",lines, buf);
strtrm(buf,'%'); // terminate at comment character
int ntokens=0;
inp = buf;
string tok[16];
while ((token=strtoken(inp,' '))!=0) {
tok[ntokens++] = token;
//printf("token %d: %s\n",n,token);
}
if (ntokens==0) continue;
device *dp;
if (tok[0]=="R") {
dp = new Resistor();
}
else if (tok[0]=="I") dp = new CurrentSource();
else {
printf("unrecognized device: %s\n",tok[0].c_str());
continue;
}
dp->parse(tok,ntokens);
element[ndevices++]=dp;
}
}
int circuit::add_node(string str)
{
int i;
for (i=0; i<ncount; i++) {
if (nodes[i]==str) return i;
}
nodes[ncount] = string(str);
return ncount++;
}
void circuit::build_node_list()
{
int i, j;
for (i=0; i<ndevices; i++) {
device &dev = *element[i];
for (j=0; j<dev.getNodeCount(); j++) dev.ndx[j] = add_node(dev.nodes[j]);
}
}
void circuit::list_nodes()
{
for (int i=0; i<ncount; i++) {
cout << i << " " << nodes[i] << endl;
}
}
void circuit::list_devices()
{
for (int i=0; i<ndevices; i++) {
device &dev = *element[i];
string s = dev.getCode() + " " + dev.name + " nodes ";
printf("%s",s.c_str());
for (int j=0; j<dev.getNodeCount(); j++)
//printf("%s ",dev.nodes[j].c_str());
printf("%d ",dev.ndx[j]);
printf("\tvalue %g",dev.value);
printf(" loc[%g %g]",dev.x,dev.y);
if (dev.orientation) printf(" rotate %g\n",dev.orientation);
else printf("\n");
}
}
Maintained by John Loomis, updated Sun Feb 04 16:05:09 2007