For each possible output Oo for the other digits: For each possible letter L for the first digit: Use recursion to output (L, followed by Oo, followed by a newline).
However, L has to get inserted "in between" the Oo outputs, which makes things tricky. Also, it isn't clear what to do when we hit the base case of the recursion.
The solution is to pass the "result so far" as a parameter for the recursion. It looks like:
We are given Op, which is some possible output for the previous digits.If there are no more digits, output Op and a newline, and return (we are done).For each possible output Oo for the next digits: For each possible letter L for the current digit: Call the function recursively, using Op + L for the new value of Op.
This way, we build up the output string as we "dive into" the recursion, and each time we "hit bottom", we get another of the possible options.
It also works to reverse the order of the two loops - that way gives a different sorting order. As an exercise, reason out what the order will be with each approach, and then test it.
Keep in mind that calculating "Op + V" is tricky in C. You can't just add strings like that; you'll have to append the V character manually.
If recursion scares you, you might be able to get your head around it by imagining that you are writing several functions: one that handles seven letters and zero digits by outputting the letters; one that handles six letters and one digit by generating each letter that's possible for the digit, and then calling the seven-letter-and-zero-digit function with each; one that handles five letters and two digits by generating each letter that's possible for the first digit, and then calling the six-letter-and-one-digit function with each of those options, etc. And then you can observe that, with a little bit of generalization work, these functions are actually all the same. And there's really nothing different about a function calling itself, versus calling another function; it's still calling a function, which works in the same way, with the new call getting its own copy of parameters and local variables. You just have to make sure that you don't get stuck in a loop, by defining a base case.