Jump to content



Photo

using rand in a "secret number game"


  • Please log in to reply
8 replies to this topic

#1 Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 24 September 2013 - 16:30

Okay so I have completed this assignment after clarification that I could have hardcoded the "secret letter", but before that I was trying to use rand and this is what I have:

#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "time.h"

void main() 
{

	int min = 97;
	int random = rand() % 25;
	int letter = min + random;
	bool correct = false;
	
	srand(time(NULL));

	do{
		printf("Please enter in your guess in lower case: \n");
		char guess = getch();
		if(putchar(letter) == guess)
		{
		printf("That's correct!");
		correct = true;
		
		}
		printf("\n");
	
	}while(putchar(letter) != true);
	
	


}

I am wondering what I could have done to make this code work instead of hardcoding what I used after talking with the professor about how he wanted us to do this. 




#2 Kalint

Kalint

    Neowinian Senior

  • Tech Issues Solved: 2
  • Joined: 16-January 07

Posted 24 September 2013 - 16:43

I'll just tell you what someone has told you in every one of your posts.

#include <stdio.h>


#3 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 24 September 2013 - 16:45

I tried using that and with the program that I use for coding it won't accept the <stdio.h> ...in fact it wont accept anything <blahblahblah.h> inside those thingys...it's really picky and only likes the "blahblahblah.h".  I addressed this with my professor previously and he did tell me that on some versions of the program that we use it won't accept the <> for the extensions and for what we are doing the "stdio.h" extension is fine.



#4 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 12
  • Joined: 26-October 05

Posted 24 September 2013 - 17:01

You must call srand() before you use rand(). The point of srand is to provide a seed (initial value) to the random number generator, so that it generates a different sequence on every run of the program. Seeding srand() with the value returned by time() ensures that a different seed is chosen every time the program is run. As it currently stands, your program chooses a random letter, but unintuively enough it chooses the same random letter every time.

 

As for headers, convention in C is to reference predefined headers like so:

#include <stdio.h>

(Note that Visual Studio creates .cpp files which are compiled as C++ by default. The above syntax will fail unless you create a .c file or choose the "Compile as C Code" compiler option (/TC). - thanks xorangekiller for the correction.)

 

In C++ all the C headers are wrapped in new headers prefixed by "c", and you drop the ".h", so it becomes:

#include <cstdio>

Note that doing #include "stdio.h" is usually fine, but angle brackets tell the compiler to skip your own header files, so it could in theory avoid conflicts. Say you have a time.h header in your program, #include "time.h" will include your header while #include <time> will include the predefined C header.



#5 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 24 September 2013 - 17:22

Ok thank you for addressing both of those Asik, ill have to give that a shot now.  I was having a heck of a time with the angle brackets....LOL! 



#6 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 24 September 2013 - 19:52

I have a few more suggestions for you. Unfortunately Microsoft does not ship a C compiler with Visual Studio anymore, so you are compiling your code with their C++ compiler instead. This works perfectly most of the time because C++ is almost perfectly backwards-compatible with C, but it has the unfortunately side effect of the compiler accepting C++ features where it should not. The most obvious use of a C++ specific feature in your code is bool. There is no boolean type in C; it is assumed that you will use int instead. The convention is that 0 is false and anything else (typically 1) is true. In case it makes my point more clear, the Clang diagnostic information highlighting your mistake is below.

rar.c:12:2: error: use of undeclared identifier 'bool'
        bool correct = false;
        ^
rar.c:22:3: error: use of undeclared identifier 'correct'
                correct = true;
                ^
rar.c:22:13: error: use of undeclared identifier 'true'
                correct = true;
                          ^
rar.c:27:28: error: use of undeclared identifier 'true'
        }while(putchar(letter) != true);
                                  ^
1 warning and 3 errors generated.

Another potential point of concern is that you have several Microsoftisms (non-portable code that is only accepted on Windows or by Visual Studio's compiler). The most obvious of which is your declaration of main(). It is mandated by the C standard that main() always return an integer value, which should be 0 if your program completed successfully. Therefore void main() is a Microsoftism. You should replace it with int main() and insert return 0; as the last line in your program. Another such Microsoftism is your inclusion of the Windows-specific header conio.h and use of getch(). Although it is not immediately obvious unless you lookup the getch() documentation on MSDN, it has long been deprecated in favor of the C standard library function getchar(), which behaves in much the same manner. Therefore you should remove "include <conio.h>" and replace getch() with getchar(). The Clang diagnostic information highlighting these problems is below.
 
rar.c:3:10: fatal error: 'conio.h' file not found
#include <conio.h>
         ^
rar.c:6:1: error: 'main' must return 'int'
void main() 
^
rar.c:18:16: warning: implicit declaration of function 'getch' is invalid in C99 [-Wimplicit-function-declaration]
                char guess = getch();
                             ^
1 warning and 2 errors generated.

As for headers, convention in C is to reference predefined headers like so:

#include <stdio>
(Note no .h at the end. This might be what your compiler was complaining about.) In C++ all the C headers are wrapped in new headers prefixed by "c", so it becomes:
#include <cstdio>
Note that doing #include "stdio.h" is usually fine, but angle brackets tell the compiler to skip your own header files, so it could in theory avoid conflicts. Say you have a time.h header in your program, #include "time.h" will include your header while #include <time> will include the predefined C header.

 
Your point about the inclusion of C headers in C++ is correct, however dropping the ".h" for standard library headers in C is not correct. That is the convention for C++ standard library headers (such as iostream and vector), but has never been convention in C. To prove my point I made the changes you proposed to the OP's program and tried compiling with Clang 3.0 and GCC 4.7; the output is below.

Clang:
rar.c:1:10: fatal error: 'stdio' file not found
#include <stdio>
         ^
rar.c:2:10: fatal error: 'stdlib' file not found
#include <stdlib>
         ^
rar.c:3:10: fatal error: 'time' file not found
#include <time>
         ^
3 errors generated.
GCC:
rar.c:1:17: fatal error: stdio: No such file or directory
compilation terminated.


#7 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 12
  • Joined: 26-October 05

Posted 24 September 2013 - 20:25

Unfortunately Microsoft does not ship a C compiler with Visual Studio anymore, so you are compiling your code with their C++ compiler instead.

/TC compiles as C. http://msdn.microsof...y/032xwy55.aspx By default .cpp files are treated as C++ and .c files are treated as C. It's surprising that this wasn't pointed out by the instructor.  :/

 

Your point about the inclusion of C headers in C++ is correct, however dropping the ".h" for standard library headers in C is not correct. That is the convention for C++ standard library headers (such as iostream and vector), but has never been convention in C. 

 

Oops, I stand corrected.



#8 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 12
  • Joined: 26-October 05

Posted 24 September 2013 - 20:31

Therefore void main() is a Microsoftism. 

void main() is also accepted by GCC AFAIK. Granted, that doesn't make it any more correct :p



#9 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 24 September 2013 - 20:52

/TC compiles as C. http://msdn.microsof...y/032xwy55.aspx By default .cpp files are treated as C++ and .c files are treated as C. It's surprising that this wasn't pointed out by the instructor.  :/

 
Thanks! I had no idea that VC++ had a switch for that. I guess I just don't work with Windows often enough anymore; I must be getting rusty.

 

void main() is also accepted by GCC AFAIK. Granted, that doesn't make it any more correct :p

 

GCC allows void main() only when its standards-compliance mode is set to gnu89, gnu99, or gnu11. The GNU standards-compliance modes accept the C standard with GNU extensions. In recent versions of GCC gnu99 is default, and in older versions gnu89 was default, therefore you are absolutely correct. Strict ISO C compliance can be forced by specifying -std=c99 on the command line (which I always do). That said, your point is well taken. It is not only Microsoft that doesn't always strictly follow the standard. In all fairness, recent versions of GCC and Visual Studio have improved their standards-compliance dramatically, both largely pushed by Clang/LLVM, which has made strict standards-compliance a priority from the beginning.