Lab 3: The Resistor Network Program
Objectives
The objectives of this assignment are for you to practice: (1) the use of C++ I/O streams, includingerror handling, (2) dynamic allocation and de-allocation of one-dimensional arrays, (3) solve aproblem using object-oriented programming. You will do so through the design of a program thatparses circuit building commands from the standard input, displaying appropriate error messages ifnecessary, and by creating and maintaining resistors in a circuit. You will be asked to calculate thevoltage at certain nodes.
Problem Statement
Your task is to implement a program for storing resistors in a circuit. The circuit, or network, is define
by a number of nodes, each node being connected to one or more resistors. Each resistor hascertain values associated with it, including: resistance value, text name, and the IDs of the two node
(endpoints) it connects. The diagram below (Fig 1) illustrates an example. Here R1 connects nodesand 2, R2 does the same, and R3 connects nodes 1 and 3. The nodescould be strips on abreadboard for example, with resistors plugged in to some nodes.
The program you will write is similar to the "input-and-store-the-network" portion of real programsused to simulate electric circuits, and programs that control the robots that automatically insertresistors connecting the appropriate points (nodes) on circuit boards.Fig. 1: Example of a circuit
Circuits are input using a text-based user interface. Commands are defined to allow the user to
insert, modify, delete and print resistors, and to set the maximum size of the network. Based on thecommands given, you will need to maintain two arrays, one of Resistors and one of Nodes, to which
you can add and modify elements.
Specifications
It is important that you follow the specifications below carefully. Where the specification says shall o
must (or their negatives), following the instruction is required to receive credit for the assignment. Iinstead it says may or can, these are optional suggestions. The use of should indicates arecommendation; compliance is not specifically required. However, some of the recommendations
may hint at a known-good way to do something or pertain to good programming style.Example input and output for the program are provided at the end of this document for yourconvenience. They do not cover all parts of the specification. You are responsible for making sure
your program meets the specification by reading and applying the description below.
Coding Requirements
The code you will write shall be contained in only three source files namedmain.cpp
,
Resistor.cpp
and
Node.cpp
. Skeletons of the files are released with the assignment's zip file.
The zip file also contains two header files:
Resistor.h
,
Node.h
. These files are NOT to be
modified in any way. Modifying these files often results in a mark of 0 for the assignment.
However, you may make use of helper functions to split up the code for readability and to makeeasier to re-use. These functions (and their prototypes) must be in one of the aforementionesource files. That is, you must not add any new header or source files.Input and output must be done only using the C++ standard library streams
ciancout
.
- The stream input operator
>>
and associated functions such as
fail()
and
eof()
shall be use
for all input. C-style IO such as
printf
and
scanf
shall not be used.
- Strings shall be stored using the C++ library type
string
, and operations shall be done using its
class members, not C-style strings.
- C-library string-to-integer conversions (including but not limited to
atoi
,
strtol
, etc) shall not b
used.
The commands your program must accept are those specified in Table 2. In addition to checking the
commands are syntactically valid, in this lab you will store the resistors and their connectivity in two
arrays (of Resistors and of Nodes) and output the correct data in response to the print commandsThe first line of input to your program will set the maximum allowed node number and the maximum
number of resistors:maxVal maxNodeNumber maxResistors
where bothmaxNodeNumberand
maxResistors
are positive integers. You should store these two valuin variables in your program and also use them to specify the appropriate size for the resistor and
node arrays your program will require.Use the
new[]
operator to allocate the node and resistor arrays. If your program is sent several
maxVal
commands during one run, you will have to ensure that for any
maxVal
command after the
first one you delete any already allocated Node and Resistor arrays, and then allocate the arrays tothe specified new sizes. The node and resistor arrays and any other necessary variables should be
initialized to the empty network state (no resistors stored) after any
maxVal
command.
The resistor index shall be the position of the resistor in the resistor array, starting at 0. The program
shall be able to accommodate exactly
maxResistors
, as specified in the
maxVal
command. The
nodes to which these resistors can be attached are identified by an integer ID, which corresponds to
their index in the node array. You must be able to store data for node indices from 0 to
maxNodeNumbe
- 1
, inclusive, where
maxNodeNumber
is set by the
maxVal
command. Nodes entered by the user
range from 1 to
maxNodeNumber
, but are transferred to indices by subtracting 1. Each node can
accommodate only a limited number of resistors attaching to it (think of the number of holes in a
breadboard strip); this is a
#define
constant
MAX_RESISTORS_PER_NODE
which is set to 5 for this lab.
The node and resistor arrays shall be sized according to the
maxVal
command, start empty and be
modified based on user commands. The command parser must check its input for validity, catching
and reporting the errors. Lastly, successful commands must update the data structures and produce
output as discussed below. Additional restrictions on how the program is to be written and organized
are detailed below.
Command Line Input
Input will be given one command on one line at a time. The entire command must appear on one lin
All input must be read using the C++ standard input
cin
.
The program shall indicate that it is ready to receive user input by prompting with three greater-than
sign followed by a single space (
>>>
); see end of this page for an example.
Input shall always be accepted one line at a time, with each line terminated by a newline character
newline character is input by pressing
Enter
. If there is an error encountered when parsing a line,
the program shall print an error message (see Section~
Table 3), the line shall be discarded, aprocessing shall resume at the next line. The program shall continue to accept and process input un
an end-of-file (
eof
) condition is received
eof
is automatically provided when input is redirected froa file. It can also be entered at the keyboard by pressing Ctrl-D. Each line of valid input shall startwith a command name, followed by zero or more arguments, each separated by one or more space
characters. The number and type of arguments accepted depend on the command. The argumentand their permissible types/ranges are shown below in Table 1.
Argument Description, type, and range nameA 代 写The Resistor Network Program string consisting of any non-whitespace characters. Whitespace characters are tab,space, newline, and related characters which insert "white space''; they mark theboundaries between values read in by operator<<, except the stringallwhich wereserve for special use characters.
nodeidNode ID, an integer ranging from 1 to maxNodeNumber
resistance Positive resistance value (typedouble)
Table 1: Acceptable input argumentsThe valid commands, their arguments, and their output if the command and its arguments are all
legal are shown below in Table 2. The program shall verify that the command and arguments are
correctly formatted and within range, and that a command is followed by the correct number of
arguments, on the same line. The handling of command names shall be case-sensitive. If there is a
error, a message shall be displayed as described in Table 3. Otherwise, a successful command
produces a single line of output on the C++ standard output,
cout
, as shown in Table 2. The values
in italics in Table 2 must be replaced with the values given by the command argument. Strings must
be reproduced exactly as entered. Where nodeids are printed, they shall appear on the order entere
in the command. Resistance values shall be printed in fixed point format with exactly two decimal
places, regardless of the number entered.
The valid commands, their arguments, and their output if the command and its arguments are all
legal are shown below in Table 2.
Command Arguments
Output if valid
Action if valid
maxVal
maxNodeNumber
maxResistors
New network: max node
number is
maxNodeNumber; max
resistors is maxResistors
Node array created with new[] to
store nodes from 0 to
maxNodeNumber and Resistor
array created to store up to
maxResistors; the network is
initialized to empty (no
resistors).
insertR
name resistance
nodeid nodeid
Inserted: resistor name
resistance Ohms nodeid ->
nodeid
Adds 1 resistor to Resistor array
and updates 2 entries in Node
resistor name not found
The resistor name entered at modifyR or printR
is not found
node value is out of permitted range 1 -
maxNodeNumber
An integer nodeid value has been provided that
is out of range
both terminals of resistor connect to same node
The two nodes to which a resistor connects
cannot be the same
Table 3: List of errors to be reported, in priority orderThe program must check that the input is valid. It must be able to identify and notify the user of the
following input errors, in order of priority. Where multiple errors exist on one input line, only one
should be reported: the one that occurs first as the line is read from left to right. Errors shall cause a
message to be printed to
cout
, consisting of the text "Error:'' followed by a single space and the err
message from Table 3. Error message output must comply exactly (content, case, and spacing) with
the table below to receive credit. There are no trailing spaces following the text.
The program is not required to deal with errors other than those listed in Table 3.
The
Resistor
Class
Each object of the
Resistor
class holds information about one resistor in the network. In
Resistor.cpp, you must implement all the functions indicated in Resistor.h. Each resistor object has
string (
name
), a resistance value in Ohms (
resistance
), and the IDs (indices in the node array) of th
two nodes to which it is connected (
endpointNodeIDs[2]
). There is are also a constructor and
destructor function to initialize the class, a function to print the values, and functions to set/get the
data members of the class. The program shall store all resistors in an array, starting at element 0 fo
the first resistor added and incrementing from there. When adding a
Resistor
to a
Node
, the resist
shall be referred to by its position in the resistor array, also known as its resistorID. Be mindful of
what is an index and what is the node number. The Resistor.h file has multiple comments to help yo
implement the member functions.
The
Node
Class
The starter code for class
Node
is in Node.h and Node.cpp. The variable
numRes
is intended to stor
the number of resistors currently attached to the node. It should start at zero, and increment each
time a resistor is added. The Node.h file has multiple comments to help you implement the member
functions in Node.cpp.
Bonus: The
solve
command
For 1% of the course grade bonus, the solve command first determines the voltage of every node,
and then it prints the voltage of every node in ascending node order. To find the voltage at every no
in a network, we can follow the iterative procedure below. The iterative procedure we are using to
solve for the node voltages is called the Gauss-Seidel method. It is a very general method of solving
linear systems of equations, and is used to solve circuits and other systems of equations with
thousands or even millions of unknowns.
Initialize the voltage of all nodes without a specified (setV) voltage to 0.
while (some node’s voltage has changed by more than MIN_ITERATION_CHANGE) {
for (all nodes without a set voltage) {
set voltage of node according to Eq. 3
}}
The voltage of a node is computed from the voltages of its neighbours according to Kirchoff’s currenequation, which states that the total current entering or leaving a node must be 0. Consider node_0below, which is surrounded by 3 resistors to 3 other nodes, as shown in Fig. 2. The total currententering node_0 must be:We can rewrite this using the fact that the current through each resistor is simply the voltage acrossvided by its resistance.earranging and solving for the voltage at node_0,elds:You can safely assume that at two nodes will have their voltage set before typing the
solvcommand.
Fig 2: A portion of a resistor network. Node 0 is connected to three other nodes as shown.
The iterative procedure above determines what voltage a node must have for it to balance the currecoming through all the resistors connected to it. Once we update the voltage of some node (say nod0), however, the voltage of other nodes (e.g., node #1) connected o that node may have to changto ensure the current flowing into them is in balance. Hence weiterate through all the nodes,repeatedly updating the voltages of those that do not have a fixed (
setV
) voltage according to Eq. 3
until no voltage changes much --- at that point we have converged to a solution.
For this lab, you should iterate until no node changes by more than
MIN_ITERATION_CHANGE
, which yo
should define to be 0.0001.Once your solver has converged, print (to
cout
) the voltage of every node that has at least one
resistor connected to it, in ascending node order. For the example shown in Fig. 3, the solve
command would print:
Solve:
Node 2: 0.30 V
Node 3: -0.02 V
Node 4: -0.60 V
Node 5: 0.52 V
Node 6: 1.00 V
Fig 3: A more complex resistor network. Two nodes have been connected to voltage source
with setV, and our program will solve for the other 3 voltages.
Hints
- You can check a stream for end-of-file status using the
eof
member function.
- To save typing, you can create one or more test files and pipe them to your program. You can
create a text file using a text editor (try
gedit
,
gvim
, or the VSCode editor). If your file is calledtest, you can then send it to your program by typingcircuit < test. Building a good suite of
test cases is important when developing software.
- If you want to look ahead ("peek'') at what character would be read next without actually reading
it,
peek()does that. For instance, if you type "Hello'' then each time you runpeek()you will ge
'H'. If you read a single character, it will return 'H' but then subsequent calls to peek() will return'e'.
- When interacting with your program from the keyboard, Ctrl-D will send an end-of-file (eof)marker.
- Reading fromcin
removes leading whitespace. When reading strings, it discards all whitespaccharacters up to the first non-whitespace character, then returns all non-whitespace charactersl it finds another whitespace. For integers (numbers), it skips whitespace and reads to the firnon-digit (0-9) character.6. Remember you can use the debugger to pause the program, step through it, and view variableincluding strings).
- If you decide to pass the string stream you created to a function, remember that string streamsand other types of streams for that matter) can only be passed by reference, not by value.IO manipulators (see header file<iomanip>
) can be used to control the appearance of output. Yomay need at leassetprecision
.
- You will need to store one array of
Nodesand one ofResistors
- global scope is acceptable for
program of this scale. You will also need a variable such as
resistorsCount
to count the numbe
of resistors already added, and will need variables to store
maxNodeNumber
and
maxResistors
.
- For output formatting (padding, left/right justify, precision control) you should look at the<iomanip> header file (www.cplusplus.com/reference/iostream (http://www.cplusplus.com/reference/iostream) is a good reference). Functions like left, right, setfiand setw will be of great help.
- Add features one-by-one. Even if you cannot complete every command (or detect every error),you should still submit your program since it may pass some test cases.
- Your program should delete all the memory it allocates with new before it exits; this is goodpractice and ensures there are no memory leaks. The autotester will check if your program
deletes all the memory it should and you will lose marks if you do not. A good way to check if yo
have deleted all the memory you allocated with new is to run the valgrind memory checking
program. A tutorial on valgrind will be posted to Quercus, and you are encouraged to learn and
use this tool.
A suggested (but not mandatory) structure for your code appears in the skeleton main.cpp file
released within the assignment's zip file.
Procedure
Create a sub-directory called lab3 in your ece244-labs directory, and set its permissions so no oneelse can read it. Download the lab3_release.zip file, un-zip it and place the resulting files in the lab3directory. There are three source files in which you will add your code. The first is main.cpp in whichou will write the command parser code. The second and third files are Node.cpp and Resistor.cppwhich you will implement the classes
NodeandResistorrespectively. All files
are in the directory lab3_release. You must not rename these files or add more files.The release also contains two include files Node.h and Resistor.h. You may NOTmodify these file to add to or delete from their content. Modifying the files commonly results in a mark of zero for theassignment. In addition, there is a Makefile to separately compile your project. Run
标签:node,Network,shall,resistor,will,program,command,Program,Resistor From: https://www.cnblogs.com/comp9313/p/18463469