This is difficult for me to put into words, but say I have some function:
a = a + b;
printf("HI THERE");
b = a + c;
(pretend this is 30 lines instead of 3 lines). Now say I want to do the exact same thing again later on, except instead of printing “HI THERE” I print “HO THERE”. What I currently do is copy paste all the lines of this function just to change HI THERE to HO THERE. This isn’t very elegant for large code blocks.
I know one solution might be like:
adder_function(1);
adder_function(2);
void adder_fuction(int input) {
a = a + b;
printer_function(input);
b = a + c;
}
void printer_function(int input) {
if (input == 1) printf("HI THERE");
if (input == 2) printf("HO THERE");
}
But this seems to be inelegant as well for more complex blocks of code. Any ideas for better solutions?
EDIT: Just to show what it is I’m doing, here’s the code in question (you can see that almost nothing changes between the blocks except .input and .output and the printf statements):
found=line.find("INPUTS");
if (found == 0) {
inputfound = true;
found = line.find_first_of(":");
if (found == string::npos) {
printf("BAD NETLIST INPUT DECLARATION\n\r");
exit(1);
}
found = line.find_first_not_of("\n\t ",found+1);
if (found == string::npos) {
printf("BAD NETLIST INPUT DECLARATION\n\r");
exit(1);
}
else {
temp_node_name += line[found];
for (i = found+1; i < line.size(); i++) {
if ( isalnum(line[i]) || isspace(line[i]) ) {
if ( isalnum(line[i]) )
temp_node_name += line[i];
if ( isspace(line[i]) || i == line.size() - 1 ) {
if (!temp_node_name.empty()) {
if (determine_uniqueness(temp_node_name)) {
nodes.push_back(dummy_node);
nodes.at(id_counter).name_in_netlist = temp_node_name;
nodes.at(id_counter).input = true;
temp_node_name.erase();
id_counter++;
}
}
}
}
else {
printf("BAD NETLIST INPUT DECLARATION\n\r");
exit(1);
}
}
}
printf("NETLIST INPUT DECLARATION OK\n\r");
continue;
}
SEPARATE CODE BLOCK THAT IS COPY PASTED
found=line.find("OUTPUTS");
if (found == 0){
outputfound = true;
found = line.find_first_of(":");
if (found == string::npos) {
printf("BAD NETLIST OUTPUT DECLARATION\n\r");
exit(1);
}
found = line.find_first_not_of("\n\t ",found+1);
if (found == string::npos) {
printf("BAD NETLIST OUTPUT DECLARATION\n\r");
exit(1);
}
else {
temp_node_name += line[found];
for (i = found+1; i < line.size(); i++) {
if ( isalnum(line[i]) || isspace(line[i]) ) {
if ( isalnum(line[i]) )
temp_node_name += line[i];
if ( isspace(line[i]) || i == line.size() - 1 ) {
if (!temp_node_name.empty()) {
if (determine_uniqueness(temp_node_name)) {
nodes.push_back(dummy_node);
nodes.at(id_counter).name_in_netlist = temp_node_name;
**nodes.at(id_counter).output = true;**
temp_node_name.erase();
id_counter++;
}
}
}
}
else {
printf("BAD NETLIST OUTPUT DECLARATION\n\r");
exit(1);
}
}
}
printf("NETLIST OUTPUT DECLARATION OK\n\r");
continue;
}
I’m late to the party so I’ll only be addressing your updated code.
First off, I see you printing error messages to
stdout(viaprintf) and then callingexit. Why? You should print error (and perhaps debugging) messages tostderr(withfprintf(stderr, ...)or withperror, thoughperroris better if a library routine fails and setserrno). Also, since this is C++ (not plain C), you might want to useiostreams instead of*printf. It’s more C++-ish (though, as predominantly a C programmer, I prefer*printfmyself).Since the only difference between your two blocks of code is the string containing
INPUTin the first andOUTPUTin the second, I recommend stuffing all of this into a function that, among other necessary parameters (whateverlineis is probably one of them), takes a parameter calledbool is_input. The first time you call this,is_inputshould betrue, and the second time, it should befalse.Then, in both of your blocks of code, you can change the
printflines to:or
And then for the member modification write:
(Note that there’s no need to use
.attwice in a row with the same index – if it threw the exception once, it won’t reach the second call, and if it didn’t throw the first time it won’t throw the second. It probably won’t be a huge speedup, but it’s the thought that counts?)Last, if you need the external variables
inputfoundandoutputfoundto be set, add abool &foundparameter to your function, and set it to betrueinside the function. The first time you call it, passinputfound, and the second,outputfound.Now your two code blocks are identical, and can be put together into one function, and called twice (once with
"INPUT", and once with"OUTPUT"). Easy.In the future, whenever you find yourself writing a block of code that’s strikingly similar to another block of code, stop rewriting (or copy-and-pasting). Copy the block of code into a new function all by itself, and replace the original block with a call to the new function. Now you can reuse that block of code as many times as you want.