hello guys...i'm rookie in C...just starting out...:$

Well...the program i was trying to write was make a series like:

0
10
010
1010
.
.
.
Now i wrote a program. But it's kinda behaving weird.
Let me show your the output:

enter the no of rows you want: 4
0
10
010
1010

Do you want to check it again?y/n:  wrong instuction,retry
Do you want to check it again?y/n:

if 'y' it's starting again, if 'n' then getting out...for others showing 'wrong instuction'

So you can see the 'wrong instuction,retry' is geting added with 'Do you want to check it again?y/n:' !!!!:-/...then again asking 'Do you want to check it again?y/n:'

here's the code:

#include <stdio.h>
#include <conio.h>
int main(){
	int i,i2,row,mod;
	char ch;
	while(ch){
		printf("enter the no of rows you want:");
		scanf("%d",&row);
		for(i=0;i<=row-1;i++)
		{
			mod= i%2;
			for(i2=0;i2<=i;i2++){
				printf("%d",mod);
				if(mod==0){mod=1;}
				else{mod=0;}
			}
			printf("\n");
		}
		while(ch)
		{
			printf("\rDo you want to check it again?y/n: ");
			scanf("%c",&ch);
			if(ch=='n')
			{
				printf("\nGoodbye");
				getch();clrscr();exit();
			}
			else if(ch!='y')
			{
				textcolor(RED+BLINK);
				cprintf("wrong instuction,retry\n");
				textcolor(7);
			}

			else
			{ break; }

		}
	}
	return 0;
}

and here i tried again changing the infinite loop:

#include <stdio.h>
#include <conio.h>
int main()
{
	int i,i2,row,mod;
	char ch,temp=1;
	while(temp==1)
	{
		printf("enter the no of rows you want:");
		scanf("%d",&row);
		for(i=0;i<=row-1;i++)
		{
			mod= i%2;
			for(i2=0;i2<=i;i2++)
			{
				printf("%d",mod);
				if(mod==0){mod=1;}
				else{mod=0;}
			}
			printf("\n");
		}
		temp=0;
		while(temp==0)
		{
			printf("\rDo you want to check it again?y/n: ");
			scanf("%c",&ch);
			switch(ch)
			{
				case 'n':
				{
					printf("\nGoodbye");
					getch();clrscr();exit();
				}
				case 'y':
				{
					temp=1;break;
				}

				default:
				{
					textcolor(RED+BLINK);
					cprintf("wrong instuction,retry\n");
					textcolor(7);
				 }
			 }

		}
	}
	return 0;
}

am i missing something?? :confused:I'm really worried coz i think i got some misconception somewhere, which i need to fix.

jephthah commented: correct formatting on the first post! yay. and you even had "int main()" +6

Recommended Answers

All 12 Replies

After you enter something with scanf(), there will always be a newline char, left in the keyboard buffer.

If you are scanf()'ing for a char, that is critical, because the newline '\n', is itself, a char. So when scanf() pulls in the char (the newline), it says "I've got my char, so I'm leaving", and your code seems to "skip" the scanf() for the char, entirely.

It did not skip it, it just got a char, and went on!

Add this right after your scanf()'s:

getchar();

That will pull one newline, off the keyboard buffer. It's not necessary if the scanf() is only for numbers, because scanf() will skip over whitespace when it's looking for numbers, anyway.
A newline is considered "whitespace", to scanf(), when it's looking for numbers.

commented: adding getchar is a bandaid. one of those cheap generic bandaids that falls off the first time you jump into the pool. i dont want your nasty bandaids floating in my pool -1

The extra '\n' from where you take in the number and press enter gets stuck in the input stream and carries down to your other prompt causing the wrong instruction error to come up (since '\n' !='y').

Here's a couple of tutorials to get you through the problem.
Particularly read the section on fgets/sscanf for your "rows" input.
http://www.daniweb.com/tutorials/tutorial45806.html
In this one read the getchar part and try to adopt it to your code.
http://www.gidnetwork.com/b-60.html

In a situation like you have here it can't hurt to initialize ch to 'y' when you declare it. As it was before the program was skipping over the loop completely.

the quick answer is that youve got unbuffered input due to your use of scanf()

but you've got a number of bad programming practices here, that i can't ignore. I suspect the blame is due to incompetent instructors teaching substandard curriculum on compilers that are 15 years out-of-date.

So I'm just going to lay it out, and if you choose not to take this advice ... well, at least I told you.

the non-standard <conio.h> library is obsolete. cease using it. this means that you will not be able to use things like "textcolor" which is unnecessary now that the days of DOS has been over for at least 10 years, and "clrscr" which is always obnoxious. you will not be able to use "getch" either, but don't worry the standard-C library <stdio.h> has "getchar" which will suffice. But you'll really want to use "fgets" anyhow, for most console input.

do not use "exit()" to quit a program due to normal events. this is a terrible practice, and will cause all sorts of problems once you start writing real programs that interface with real hardware and live databases.

steer away from using scanf(). the lure is tempting, but you need to learn to avoid it. its the source of many problems. fgets() will get a string safely that can be converted to numeric value and allows a relatively easy error-checking method to ensure the input buffer is cleared in case input is too long. (i'm not going to do this error checking here, just to keep things simple)

i'm going to rewrite your program. the logic of the series writer is fine, but the rest (input/output) just needs to go. see what i do here, and spend the time to understand whats happening and why i do it this way

#include <stdio.h>
int main()
{
    int i, j, row, mod, temp=1;
    char inputStr[32];  // made longer than reasonble input will is expected
                        // error checking should still be employed 
                        // to clear buffer overflow, if input is too long
    while(temp==1)
    {
        row = 0;
        while (row <= 0)
        {
            printf("\nEnter the no of rows you want: ");
            fflush(stdout);     // printf did not have newline, need to flush
            fgets(inputStr,31,stdin);
                                // error checking should go here for buffer overflow
            row = atoi(inputStr);
            if (row <= 0)
                printf("invalid input, try again\n");
        }

        for(i=0;i<=row-1;i++)
        {
            mod= i%2;
            for(j=0;j<=i;j++)
            {
                printf("%d",mod);
                if(mod==0){mod=1;}
                else{mod=0;}
            }
            printf("\n");
        }

        while (1)
        {
            printf("\nDo you want to check it again?y/n: ");
            fflush(stdout);     // printf did not have newline, need to flush
            fgets(inputStr,31,stdin);
                                // error checking should go here for buffer overflow
                                
            if (inputStr[0] == 'y' || inputStr == 'Y')
            {
                temp = 1;   // outside while loop will continue
                break;      // breaks out of this inside while loop
            }
            
            else if (inputStr[0] == 'n' || inputStr == 'N')
            {
                printf("\nGoodbye");
                temp = 0;   // outside while loop will end
                getchar();
                break;      // breaks out of this inside while loop
            }
            
            else    // continue this inside while loop until valid response
                printf("wrong instuction,retry\n");
        }
    }
    return 0;
}

.

commented: Awsome...thanks!! +0

Add this right after your scanf()'s:

getchar();

this is wrong. its sloppy and it barely addresses the problem. in practice, with more complex inputs, it will fail more often than it works.

if the user enters a number followed by enter, like this: "12\n" , adak's suggestion will work

but if the user input diverges from that in the slightest (and it will) ... if they enter other stuff after the number (a "\tab" or a space " " or some other input), like this: "12 \n" ... it will still fail to work correctly.

do not use scanf. use fgets to a string, then convert the string to an integer, long, float or double using "atoi" "atol" "atof" or "atod"... even better are the functions "strtol" and "strtod"

.

fgets() is the user input function of choice, for serious programs.

Students who haven't got into qualifying user input yet, are frequently left with scanf(). It's used heavily in books teaching C, and by the instructors, as well.

So it's better to learn how to work with scanf(), than to say "don't use it ever". That's good advice for serious program user input, but it's just sticking your head in the sand, for students learning C.

scanf() will be used in their classes, by their classmates and instructors, and by the majority of the books they'll be using for the course.

Just remember that scanf() was designed for FORMATTED input, not for "Miss Piggy practices keyboarding". ;)

i can see your point. there's value to keeping it simple. and often i won't bother trying to correct the use of scanf(), when the issue being addressed is unrelated.

but in this case, i disagree, because the very problem is due to scanf(). it doesnt take Miss Piggy to come along and fatfinger a user entry all to hell. So your getchar() is just putting lipstick on a pig. And then walking that pig to a synagogue on Yom Kippur. While munching on a bag of pork rinds.

wait, what?

okay, never mind. i'll agree to disagree, and leave your scanf()s alone from now on.

.

Thanks guys for helping. I was busting my own balls and trying to figure it out last 2 days.
Yeah Adak is right. All my friends use this scanf thing and all our teachers do and indeed they encourage us to use scanf. Now for using fgets() i may get a negative feedback from them. But i'm serious with my programming and want to get rid of the things which are bad practices in the beginning. Cause if i get used to one thing, it'll take a lot to get rid of in the future. Thanks for your help adak.

@jonsca...thanks for the links mate. I'll definitely check those out.

@jephthah...thanks man...yeah...those books are 15 years old maybe. Don't know why these people update them with time. thanks for showing me where i was doing wrong. I never saw our teachers using textcolor, clrscr or exit()...i found those in turbo c's help section, and always wonderd why people don't use it. I thought it was soo cool and useful. ;) Everyone kept telling me don't use 'goto'. That's a bad practice. Except goto you can use everything else. I'll definitely use this good alternatives. Seems long way to go...lolz...:twisted:

First things first....First going to remove this compiler from my pc.... :@

i'll take back my neg assumptions of your instruction/curriculum. i thought you were from the indian subcontinent, or southeast asia. because they apparently have entire universities that force students to use Turbo C for some unknown reason. since you're from a western country, your instruction is probably adequate.

yes, do uninstall that compiler. it is bad. There are many good options, including MSVC. I recommend the free Code::Blocks. download the windows version that comes with MinGW compiler, it's fully modern and adheres to industry standards.

as for "fgets" its from the same <stdio.h> library that "scanf" is in. there's no reason to think you're not advanced enough to use it. Check it out, .

good luck.


.

well...you were right mate... I'm indeed from INDIA...:icon_cheesygrin: and here the university administration and teacher do force us for using old books and compilers. I found those functions from that old compiler's help section. Anyway, i want to move out. After all its the 2nd decade of 21st century.
Thanks to all...

oh, well, you have an awesome command of the english language. i thought you were a native speaker.

i feel bad for you guys out there. a bunch of really good talent, sadly being instructed in an educational system that perpetuates incompetence in the administration.

Hey jephthah,
I used your code. this are the errors i'm getting.

C:\Documents and Settings\amlan\Desktop\series1.c|17|error: `atoi' was not declared in this scope|
C:\Documents and Settings\amlan\Desktop\series1.c|41|error: ISO C++ forbids comparison between pointer and integer|
C:\Documents and Settings\amlan\Desktop\series1.c|47|error: ISO C++ forbids comparison between pointer and integer|
||=== Build finished: 3 errors, 0 warnings ===|

specially the first one...i'm not familiar with 'atoi'

Adak..i tried your trick in my old code too...now the wrong instruction now getting showed twice at the first but the loop is not working anymore. i meant, now every time it's showing wrong instruction no matter i put y or n or anything else.

never mind...i figured it out...i've to include <stdlib.h>...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.