I am new to C programming and I found what seems to be an unusual requirement in Dev-C++ that is not required in Microsoft Visual Studio 6.0. Dev-C++ seems to require that I follow scanf(....) with getchar() in this program. The progam is not very sophisticated so I may it poorly structured. It did complile however, so I thought that would indicate that the structure was not too bad.
Sorry, but I could not figure out how to include line numbers. I have a bitmap image but I was unable to attach it to this thread.
If you comment out line 39 <getchar()> the program will not work. It is my understanding that scanf(...) should have the same effect as getchar() with regard to holding the console window until the user responded. It does not do that with Dev-C++.
Did I do something wrong here?
/* This program inputs a single character A, B, C or D and outputs a number
corresponding to the character.
for input character = A the output is 1
for input character = B the output is 2
for input character = C the output is 3
for input character = D the output is 4
for input character = E...Z or other the output is 0
*/
/Henry Santana
Created: 8/6/2007
Last revision: 8/9/2007 /
include <stdio.h>
int Output, ReturnValue;
char InChar;
int TestSwitch(char Character)
{
switch(Character)
{
case 'A': ReturnValue=1; break;
case 'B': ReturnValue=2; break;
case 'C': ReturnValue=3; break;
case 'D': ReturnValue=4; break;
default: printf("Illegal character input %c \n", Character); ReturnValue=0;
}
return ReturnValue;
}
main()
{
printf("Enter A, B, C or D \n");
scanf("%c", &InChar);
getchar(); //Why is this needed?
//*********
/
getchar() required in Dev-C++.
Not required in Microsoft Visual Studio 6.0
*/
//**********
Output=TestSwitch(InChar);
printf("Output = %d \n", Output);
/ getchar() will hold the window open waiting for user input. This is
sometimes necessary when the window closes too quickly before it can be
read. To close the window press ENTER. /
printf("Press <ENTER> to close window");
getchar();
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It was great to hear from you folks. Evidently I have a lot to learn.
I chose a slightly more complex program than "Hello World" because it is a little more challenging, it wasn't designed to be useful. I had a lot of fun debugging it (It had a lot of errors).
I learned that for programs like this Basic is better. If you want to see how a good basic can be, check out MikroBasic at www.mikroe.com (Nice IDE too). Unfortunately it just generates code for microprocessors only and has no user console I/O functions but the the syntax is really nice.
Thanks to all for the prompt response. Best wishes to everyone.
H. Santana
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Actually, I first learned BASIC back in 1975, and used it on and off for the next
25+ years. I did a LOT of work with it.
For a long time, it was my first language.
I am reluctant to say any language is "better" than another - they are each
strong in certain ways. Adding new languages helps you, even if you never
use them for much. They help you understand the languages you do use better.
I learned Python just for the heck of it, and it is one of my primary languages.
Stick with it, and you will be better and richer for the experience.
Wayne
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2007-08-09
The line:
scanf("%c", &InChar);
extracts exactly one character from the input buffer, but none of the stdin functions return until you press <newline> - the input buffer is line oriented and makes no characters available until a whole line is received. So when you press:
A<ENTER>
you place two characters in the buffer.
Your getchar() trick is flawed however. If a ham fisted user typed:
AA<ENTER>
the getchar() would extract the second 'A' only, leaving you just where you were before!
A better solution is:
while( getchar() != '\n' ){ /flush line buffer/ } ;
I find it hard to believe that it is "Not required in Microsoft Visual Studio 6.0" since they use the exact same C runtime library! I just tried it in VC++ 2005 and it exhibits the same (correct) behaviour.
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2007-08-09
Just to be clear (in case it wasn't), when there are characters remaining in the buffer, subsequent scanf("%c", &InChar); calls are satisfied immediatly by whatever remains in the buffer, so fall straight through without waiting for more input.
The only way to make it work with stdio calls is to switch the console to character rather than line mode - doing that is platform specific and I am not sure that Windows or teh C runtime library even supports such a mode. The alternative is to use Win32 console API calls rather than stdio, which are not line buffered (but are much more cumbersome to use): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/console_functions.asp
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Please keep in mind that Dev-C++ is just an IDE, a fancy editor.
The compiler it uses is GCC, so anything you run into with respect to why the compiler
does something is better throught of as "Why does GCC do this?" rather than "Why does
Dev-C++" do this?"
This might seem like a symantic quibble, or an attempt to dodge blame, but understanding
this enables you to ask questions that get you, either through searching or posting, better
answers, faster.
One other point. Visual C++ 6 is a compiler that is almost 10 years old. It is old enough
that it predates the ANSI standard for the C++ language. There are a number of things that VC6
does that are no longer correct by the language standard. If you find differences between
what VC6 does, and a more modern compiler (like GCC 3.4 that Dev uses), then the odds are
pretty good that VC6 is doing it wrong.
Wayne
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2007-08-09
BTW, compiling simply means that he code is valid code. It says nothing about the quality or structure.
The only real issue I have with your code since you mentioned it is that all your variables, with the exception of the parameter "Character" are global variables, and none of them need to be - they are never accessed by more than one function so can be local to where they are used. Always aim to use the use the more restrictive scope where possible.
Making ReturnValue global, and then using it as a return value is a real howler! The caller sees both the return value and the global - you don't need both and should prefer the first ;-) After the TestSwitch() call both the globals Output and ReturnValue contain the same value.
I'm sure it is hardly the point of your exercise, but the entire body of TestSwitch() could be replaced with just:
return Character - 'B' ;
and yield the same numerical result. But then TestSwitch() would be somewhat a misnoma! ;-) Can you tell I'm bored!?
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Dev-C++ Version 4.9.9.2
Windows XP
I am new to C programming and I found what seems to be an unusual requirement in Dev-C++ that is not required in Microsoft Visual Studio 6.0. Dev-C++ seems to require that I follow scanf(....) with getchar() in this program. The progam is not very sophisticated so I may it poorly structured. It did complile however, so I thought that would indicate that the structure was not too bad.
Sorry, but I could not figure out how to include line numbers. I have a bitmap image but I was unable to attach it to this thread.
If you comment out line 39 <getchar()> the program will not work. It is my understanding that scanf(...) should have the same effect as getchar() with regard to holding the console window until the user responded. It does not do that with Dev-C++.
Did I do something wrong here?
/* This program inputs a single character A, B, C or D and outputs a number
corresponding to the character.
for input character = A the output is 1
for input character = B the output is 2
for input character = C the output is 3
for input character = D the output is 4
for input character = E...Z or other the output is 0
*/
/Henry Santana
Created: 8/6/2007
Last revision: 8/9/2007
/
include <stdio.h>
int Output, ReturnValue;
char InChar;
int TestSwitch(char Character)
{
switch(Character)
{
case 'A': ReturnValue=1; break;
case 'B': ReturnValue=2; break;
case 'C': ReturnValue=3; break;
case 'D': ReturnValue=4; break;
default: printf("Illegal character input %c \n", Character); ReturnValue=0;
}
return ReturnValue;
}
main()
{
printf("Enter A, B, C or D \n");
scanf("%c", &InChar);
getchar(); //Why is this needed?
//*********
/
getchar() required in Dev-C++.
Not required in Microsoft Visual Studio 6.0
*/
//**********
Output=TestSwitch(InChar);
printf("Output = %d \n", Output);
/ getchar() will hold the window open waiting for user input. This is
sometimes necessary when the window closes too quickly before it can be
read. To close the window press ENTER.
/
printf("Press <ENTER> to close window");
getchar();
}
It was great to hear from you folks. Evidently I have a lot to learn.
I chose a slightly more complex program than "Hello World" because it is a little more challenging, it wasn't designed to be useful. I had a lot of fun debugging it (It had a lot of errors).
I learned that for programs like this Basic is better. If you want to see how a good basic can be, check out MikroBasic at www.mikroe.com (Nice IDE too). Unfortunately it just generates code for microprocessors only and has no user console I/O functions but the the syntax is really nice.
Thanks to all for the prompt response. Best wishes to everyone.
H. Santana
Actually, I first learned BASIC back in 1975, and used it on and off for the next
25+ years. I did a LOT of work with it.
For a long time, it was my first language.
I am reluctant to say any language is "better" than another - they are each
strong in certain ways. Adding new languages helps you, even if you never
use them for much. They help you understand the languages you do use better.
I learned Python just for the heck of it, and it is one of my primary languages.
Stick with it, and you will be better and richer for the experience.
Wayne
The line:
scanf("%c", &InChar);
extracts exactly one character from the input buffer, but none of the stdin functions return until you press <newline> - the input buffer is line oriented and makes no characters available until a whole line is received. So when you press:
A<ENTER>
you place two characters in the buffer.
Your getchar() trick is flawed however. If a ham fisted user typed:
AA<ENTER>
the getchar() would extract the second 'A' only, leaving you just where you were before!
A better solution is:
while( getchar() != '\n' ){ /flush line buffer/ } ;
I find it hard to believe that it is "Not required in Microsoft Visual Studio 6.0" since they use the exact same C runtime library! I just tried it in VC++ 2005 and it exhibits the same (correct) behaviour.
Clifford
Just to be clear (in case it wasn't), when there are characters remaining in the buffer, subsequent scanf("%c", &InChar); calls are satisfied immediatly by whatever remains in the buffer, so fall straight through without waiting for more input.
The only way to make it work with stdio calls is to switch the console to character rather than line mode - doing that is platform specific and I am not sure that Windows or teh C runtime library even supports such a mode. The alternative is to use Win32 console API calls rather than stdio, which are not line buffered (but are much more cumbersome to use): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/console_functions.asp
Clifford
Please keep in mind that Dev-C++ is just an IDE, a fancy editor.
The compiler it uses is GCC, so anything you run into with respect to why the compiler
does something is better throught of as "Why does GCC do this?" rather than "Why does
Dev-C++" do this?"
This might seem like a symantic quibble, or an attempt to dodge blame, but understanding
this enables you to ask questions that get you, either through searching or posting, better
answers, faster.
One other point. Visual C++ 6 is a compiler that is almost 10 years old. It is old enough
that it predates the ANSI standard for the C++ language. There are a number of things that VC6
does that are no longer correct by the language standard. If you find differences between
what VC6 does, and a more modern compiler (like GCC 3.4 that Dev uses), then the odds are
pretty good that VC6 is doing it wrong.
Wayne
BTW, compiling simply means that he code is valid code. It says nothing about the quality or structure.
The only real issue I have with your code since you mentioned it is that all your variables, with the exception of the parameter "Character" are global variables, and none of them need to be - they are never accessed by more than one function so can be local to where they are used. Always aim to use the use the more restrictive scope where possible.
Making ReturnValue global, and then using it as a return value is a real howler! The caller sees both the return value and the global - you don't need both and should prefer the first ;-) After the TestSwitch() call both the globals Output and ReturnValue contain the same value.
I'm sure it is hardly the point of your exercise, but the entire body of TestSwitch() could be replaced with just:
return Character - 'B' ;
and yield the same numerical result. But then TestSwitch() would be somewhat a misnoma! ;-) Can you tell I'm bored!?
Clifford
Want to help me with some boat wake interpolation stuff?
Jest kidd'in
;)
Wayne