0

So I am trying to do this for practice just to get an understanding but if I have a code in say test.cpp and I want to change a line in the program say "CONST N = 10" that changes the value of N to different values through a loop in a bash script how would I do that ? My initial guess was to do:

for x in 10 20
 do 
    sed -i -e 's/const int N = 10;/const int N = '$x';/g' test.cpp
    g++ test.cpp -o test.o
    ./test.o
    sed -i -e 's/const int N = '$x';/const int N = 10;/g' test.cpp
 done

where x would run through 10, and 20 and then input those values into the variable value in the program... But I am unsure if that is what I should be doing or not. Any help would be greatly appreciated.

  • You are compiling the program before running it, yes? – Jeff Schaller Mar 21 '18 at 16:45
  • Yes I forgot to add that in my post but just before the "./test.cpp" I am compiling the program. So that is compiles after each change. – Robert Mar 21 '18 at 16:47
  • 1
    The correct syntax is for x in {10..20} to cycle from 10 to 20. You also need to escape the variable with double quotes: sed -i -e 's/const int N = 10;/const int N = "$x";/g' – Nasir Riley Mar 21 '18 at 16:54
  • 2
    Why don't you let the program read the value of the N variable when it's running? That way, you don't need to recompile it every time. – Kusalananda Mar 21 '18 at 17:27
0

The loop you have seems it should work, it would recompile the program for the values of N equal to 10 and 20.

However.

1) if you want all 11 values between 10 and 20, you'll have to use something like for x in {10..20} or for ((x = 10 ; x <= 20 ; x++)) instead.

2) Changing the source code twice seems a bit useless, it might be cleaner to keep a non-changing base version which you then modify as required, e.g.

sed -e 's/const int N = 10;/const int N = '"$x"';/g' base.cpp > test.cpp
g++ -Wall test.cpp -o test
./test
rm test.cpp test

or even something like sed -Ee 's/^(const int N =)[^;]*;/\1 '"$x"';/g' to ignore the value in the assignment completely.

3) Don't use test.o for the executable file. The .o extension hints at an object file, which you'd get by running gcc -c test.c. Also, in this case x only contains numbers, but just to be on the safe side, it's better to double-quote it, as above.


That said, modifying the program to read the number off the command line instead of recompiling for each value would not be too difficult. This would assign the first argument to N and then print it (it's in C, but as far as I know the arguments to main work similarly in C++):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int N = 10;
    if (argc > 1) N = atoi(argv[1]);
    printf("N: %d\n", N);
    return 0;
}
1

A better way would be to use a preprocessor macro, which you can define in the compilation line. So change the code to:

#ifndef N_MAC
#define N_MAC 10
#endif
const int N = N_MAC;

and then compile it with:

g++ test.cpp -DN_MAC=$x -o test.o

The $ifndef block provides a default when you don't use -DN_MAC to override it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.