The comment that 'most of the code is just printing to a file' means that the card printing code should probably be in a function of its own called from the function shown — so there'd be no need for us to analyze it. The card printing code definitely makes it harder to see the wood for the trees.
With a function:
static void print_card(FILE *outFile, const char *word, int treeLoopLevel);
the code in createoutfilecard()
reduces to:
static void createoutfilecard(int y)
{
int treeLoopLevel = 0;
char word[50];
int q;
int p;
char str[80];
if (y== 1)
{
printf("Enter the tree size: ");
scanf("%d", &treeLoopLevel);
printf("Enter the number of cards: ");
scanf("%d", &q);
}
for (p=1; p<=q; p++)
{
if (treeLoopLevel>=1 && treeLoopLevel<=10)
{
printf("Enter the recipient's name: ");
}
else
{
printf("invalid input");
printf("Enter the tree size: ");
scanf("%d", &treeLoopLevel); // Was using x!
}
if (scanf(" %49s", word)==1)
{
system("cls");
strcpy(str,"christmascard");
strcat(str,word);
strcat(str,".txt");
printf("The file will be located at %s\n", str);
FILE *outFile=fopen(str, "w");
if (outFile != 0)
{
print_card(outFile, word, treeLoopLevel);
fclose(outFile);
}
}
}
}
There are still problems here. For example, if the program fails to create (open) the file, it quietly ignores the problem. Still, that's better than crashing because the file pointer was null. The code for validating the inputs is convoluted and incomplete. The second attempt to specify the size is not validated until the start of processing the next card; the prompt for the name is not given if the size is wrong. It is still true that if the code is not called with y == 1
, there are going to be problems. I've changed the function to return void
since the only value returned was 0, and there's no point in making the caller check that.
Stylistically, loops in C should not usually be written:
for (p=1; p<=q; p++)
You should normally use the idiomatic C convention of counting from zero up to (but not including) the limit:
for (p = 0; p < q; p++)
Now, with those gripes and grumbles out of the way, you seem to want to create a list of names so you can cost the number of cards produced.
The simplest technique is simply to add an array of fixed size character strings:
enum { MAX_CARDS = 20 };
enum { MAX_NAME_LEN = 50 };
char names[MAX_CARDS][MAX_NAME_LEN];
int n_names = 0;
Then, in the code after if (scanf("%s", word) == 1)
(congratulations on checking this input — the other uses of scanf()
should also be checked, though), you can write:
strcpy(names[n_names++], word);
After the loop is complete, you can do your costing.
Please note the guidelines on how to create an SSCCE (Short, Self-Contained, Correct Example) and do not include so much extraneous material in the programs you ask questions about. Not everyone is as patient as me!