Click here to Skip to main content
15,886,016 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Can't make this function work correctly, project with this code compiles with no problems, but when i execute this function it asks for a new record name and than prints:
our record has been succesfully added
Press any Enter to go to the main menu!!!
and than exits returning 0. even though function is void. please heeelp.
p.s. function works if i use scanf ("%s", text) instead of gets (text), buts skips words after very firs white space in input. (%[^\n] doesn't work just like gets(text).
C++
void makerec()
{

    system ("cls");
    FILE *fp;
    char name[20];
    printf("Enter the name of new record:");
    scanf ("%s", name);
    fp = fopen (name, "w+");
    printf ("Input your record bellow:\n");
    char text[1000];
    gets(text);
    int length = strlen (text);
    for (int i = 0; i < length; i++)
    {
        fputc(text[i], fp);
    }
    fclose (fp);
    printf("Your record has been succesfully added\n\n");
    printf("Press any Enter to go to the main menu!!!");
    getch();
    main();
} 
Posted
Comments
lewax00 13-Feb-13 9:54am    
It's hard to say without seeing what's in main. But 0 is the default return value if main doesn't return a value.
Topuchi13 13-Feb-13 10:00am    
main just calls this and some other functions, here it is
int main ()
{
system ("cls");
printf ("********************************************\n");
printf ("****This is your personal diary software****\n");
printf ("********************************************\n\n");

printf ("Please chose your desired action(input a corresponding number): \n\n");
printf ("1. Make a new record\n");
printf ("2. View a record\n");
printf ("3. Edit a record\n");
printf ("4. Delete a record\n");
printf ("5. Take a break and play some tic-tac-toe ;)\n");
printf ("6. Change your p.diary password\n");
printf ("7. Leave your p.diary\n\n");
int a;
scanf ("%d", &a);

switch (a)
{
case 1:
makerec();
break;
case 2:
viewrec();
case 3:
editrec();
break;
case 4:
deleterec();
break;
case 5:
tictactoe();
break;
case 6:
editpassword();
break;
case 7:
printf ("Thank you for using this software\n");
exit(0);
default:
printf ("You entered a wrong number, Try again");
break;
}
return 0;
}

There are a few questions/issues.
Why is this function calling main()? That's unusual.
When you say it is returning 0, do you mean when the program exits? All programs return 0 unless you specify differently with exit(-2) for example.

I understand that many (especially older) C books use scanf, gets and similar functions for console input, or fscanf, fgets etc. for file input. PLEASE PROMISE ME YOU WILL NEVER USE THEM AGAIN.

The reason is what is called a buffer overflow. Have you ever wondered what would happen if someone typed in 50 characters instead of 20? In a high-level language the input would either be truncated or the name buffer would be resized to accomodate the data. C is a middle-level language, in this case meaning you get more power to control what actually happens in memory. By overfilling your buffer, a user could input machine code, and with some manipulation could execute their code.

If you look at about 75% of all security vulnerabilities in the last 15 years, they are due to buffer overflow exploits just like this.

I realize this is just a little program for learning, but please heed my advice as a programmer of 23 years to break this habit now. At a minimum, change this line to:

scanf ("%20s", name);


Even better, read about the safe version of these functions, which require that you specify the size of the buffer.
 
Share this answer
 
Comments
Topuchi13 13-Feb-13 10:42am    
thanks for this informative and helpful answer. I call main() to go back to main menu of program,(in idea at least :)) and remouving it doesn't solve my problem. i guess that my problem is in text i/o functions, but I couldn't understand how to solve it.
P.S I promise :):):).
Yvan Rodrigues 13-Feb-13 10:52am    
Chris is right. Now that I can see your main(), you want to loop until the user chooses to exit. The reason you don't want to do this is that if every time you choose a menu item it does something and then calls main, all that code is accumulating and eventually the program will blow up with a stack overflow error. This would probably take a long time on a modern PC but maybe just a few iterations on an embedded system or an iPhone etc.
Topuchi13 13-Feb-13 11:00am    
what about using fgets() instead of scanf and than manually add null terminator to the string with some nice loops??
Yvan Rodrigues 13-Feb-13 11:17am    
If you were wanting input of a long string when len > buflen, yes you could create a loop in which you read a fixed number of bytes and process them.
I see what is happening here.

Youi don't need to call main() from your makerec function. I think you are trying to make the menu appear again.

Your main routine needs to loop until you ask for option 7. Given that you have an exit(0) call for option 7 already then add an infinite loop aroundthe code in main.

Change

system ("cls"); 
printf ("********************************************\n");


to

for(;;) 
{
    system ("cls"); 
    printf ("********************************************\n");


then add closing brace before the return 0;

 } 
return 0; 
}


becomes

 } 
}
return 0; 
}


*EDIT* And you should follow the instructions above about the safe versions - which I've upvoted.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900