Warmup.c. How to break this code? | SoloLearn: Learn to code for FREE!

+1

Warmup.c. How to break this code?

I have been asked to write a program that receives character input from the user and prints it. The program terminates when the input is 'Q' or 'q'. Where will this code break? https://code.sololearn.com/csrLSvZ1owtN/?ref=app https://code.sololearn.com/csrLSvZ1owtN/?ref=app https://code.sololearn.com/csrLSvZ1owtN/?ref=app

c

10/28/2020 8:58:40 PM

Assaf Hillel

14 Answers

New Answer

+5

Ipang you never really need a break, a continue or a goto (exept for the breaks in the switch cases, but you don't even really need the switch control structure). Check this https://en.wikipedia.org/wiki/Structured_program_theorem I believe it's a good practice not to use them unless in cases they save you resources, like in the case you need to exit a deeply nested loop. That's because if you fill a code with break, continue and goto statements it will be definitely harder to read for humans and thus more likely to contain bugs and requiring a bigger effort to be debugged than the same code wrote using structured programming. In this small program of Assaf there's not enough code to make the difference evident, but still it is good for him to practice structured programming.

+4

Using an infinite loop and a break is really messy programming. Don't do it unless it's an assignment on using break. A more elegant solution is to use a boolean value e.g. #include <stdbool.h> bool alive = true; do { ... }while(alive); then instead of using break in your if statement use... alive = false; There is also no need for both the fgets and the scanf lines. Your code will work without the fgets line. I have tested this. To avoid buffer overflow situations you should specify the maximum number of characters to read in scanf e.g. scanf("%99s", input); //read 99 chars max If you want to be able to read strings that contain spaces use... scanf("%99[^\n]%*c", input); this reads any character except a newline to a maximum of 99 characters and stores it in input then reads the next character, but does not save it, to consume the newline character. Finally, adding a newline in the printf statement at line 16 keeps the output neater... printf("%s\n", input);

+4

Martin Taylor, Is an infinite loop which uses a break really a messy programming? taking these two illustration as example, how can we say the second is a messy programming? the first one will still execute (some instructions) before the state of <alive> is evaluated. This is not the case with the second one right? bool alive = true; do { if(some-condition) alive = false; // some instructions } while(alive); while(1) { if(some-condition) break; // some instructions }

+4

Interesting article, Davide. Thanks.

+4

You are welcome Coder Kitten! 🐈

+3

Assaf Hillel sizeof( char ) is always 1. So you can always use the number 1 instead of sizeof( char ). The fgets(input, 1, stdin) read only 1 char, but if you want to read only 1 char you can use getchar() or scanf(). If you want to read a word all at once, you can use scanf or fgets. And if you want to read an entire string made of words, numbers , spaces and characters you need fgets. I suggest you to use a loop with getchar() or scanf. In each lap of the loop you read a character, than check wether is Q and then either print the char or exit the loop.

+3

@Davide, You can read strings containing whitespace and numbers using scanf and fgets, you don't "need" to use fgets.

+3

Martin Taylor I should have said that "I need" fgets. Because laziness keep me away from learning the full capabilities of scanf. If I may, I would put part of the blame on the folks from stack overflow that say scaf is unsafe. But anyway thank you for correcting me.

+3

Ipang You can do the following: c = getchar(); While ( c != q && c != Q ) { putchar( c ); c = getchar(); } The fact that you never really need a break has been proved. Check the link that I posted.

+3

Davide You got a point 👍

+3

lpang If you don't want the instructions to be executed if the abort condition is met then use an if-else statement... bool alive = true; do { if (some-condition) { alive = false; } else { // some instructions } } while(alive);

+2

Davide Apart from `break`, is there any other suggested or better way(s) to exit a loop prematurely? if you read the OP's question: "... receives a character input from user and prints it. The program terminates when the input is 'Q' or 'q'". The second paragraph indicates a need for a loop, with an exit condition (input being either 'Q' or 'q'). Then in this case, a `break` is in order to exit the loop when the exit condition satisfies. So how come "you never really need a `break`"?

+2

Davide, I don't recall hearing people saying scanf() is dangerous. It was often stated that gets() was dangerous due to the potential for buffer overflow. Note that gets() has been removed from the standard now. Using scanf() without a length specifier for strings is just as bad as using gets(), however, the ability to specify a length with scanf() mitigates that problem.

+2

Martin Taylor you are right, as always 🙄 I checked this https://stackoverflow.com/questions/2430303/disadvantages-of-scanf#answer-2430978 and it seems that you can take care of any possible edge case input.