Jump to content


Check out our Community Blogs

ZipOnTrousers

Member Since 07 Nov 2008
Offline Last Active Dec 17 2011 04:20 PM
-----

Topics I've Started

[C] Validating user input...

28 December 2010 - 08:41 PM

Hi guys, I'm writing a little random number guessing game as a little project and I've only just realised how difficult it can be to validate user input in c... too used to Java and python where its (relatively) easier. So I wanted to write the guessing game so that the user could only enter a valid and relevant number, between 0 and 100. I have the below code and its working almost perfect:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>

typedef enum boolean {BFALSE, BTRUE} bool_t;

void die (char *msg)
/* This method takes a char array (string) as parameter and prints this as error message on failure, then exits  */

{
	fprintf (stderr, "%s\n", msg);
	exit (EXIT_FAILURE);
}

bool_t get_int (int *ival)
{
	char buff[5];
	long lval;
	char *end;
	
	if (fgets (buff, sizeof buff, stdin) == NULL)
		return BFALSE;
	
	lval = strtol (buff, &end, 10);
	
	if (lval < INT_MIN || INT_MAX < lval || end == buff)
		return BFALSE;
	
	*ival = (int)lval;
	
	return BTRUE;
}

int main (int argc, const char * argv[]) {
	int ranNum = 0, userGuess =0;
        // generate ranNum (based on time)
	srand(time (NULL));
	ranNum = (rand() % 100);
	
	printf("I have just generated a random number between 0 and 100. Can you guess it?\n\n");

	while (ranNum != userGuess) {
		// Validate input - if not a number between 0 and 100 then exit
		if (get_int (&userGuess) != BFALSE && userGuess <= 100 && userGuess >= 0)
			printf ("Your number was: %d\n", userGuess);
		else {
			die ("Invalid integer");
		}
	
		if (userGuess > ranNum) {
			printf("Wrong! Too high!\n");
			printf("Guess again:");
		}
		else if (userGuess < ranNum) {
			printf("Wrong! Too low!\n");
			printf("Guess again:");
		}
	}
	
	//If all conditions met so far, numbers must match so print success and exit
	printf("Well done! You guessed it! (Eventually...)\n");

	return 0;
}

/* End of main.c */

I just wanted to know if you guys think this is the safest way of validating user input like this? It seems an awful convoluted way of doing it as it uses two additional functions just to safely check if input is an integer... but I've heard terrible things about scanf and obviously gets is a no-go. Any opinions?

Also, I wanted to have the game continue to loop after informing the user of the invalid input... though I can't see any way of doing this that won't make the code much more complicated. If anyone has any ideas on how to improve I'd really appreciate it. (I realise this is probably not the best way to generate a random number, I just used it so it generated something. Sure there are much better ways but meh, this works as well.)

Thanks
ZipOn

[C] Bus error when prompting user for filename?

24 December 2010 - 08:35 AM

Hi guys, after a year break from any programming wanting to get back into C as I never got very far with it. I decided to just jump into a simple little program and expand it, to teach myself about file IO and pointers in a more interesting way than reading. Basically, have a Word count program to count words, spaces, punctuation and numbers. It works fine reading form user input on Command Line, but now I want to expand to include File IO. Again, it works fine when the file is just entered into the source code, but now I want the user to be able to specify the file. The code is below:

#include <stdio.h>

//Program to take a text file as input and count the number of characters, white spaces, numbers and punctuation. A tab is 4 spaces. 

int main (int argc, const char * argv[]) {

	int c, i, lastChar, tabSpaces;
	int charArray[5];
	char fileName[20];
	FILE *fp;
	
	//Initialize array
	for (i = 0; i < 5; i++)
		charArray[i] = 0;
	lastChar = 0;
	//Define how many spaces a tab is the equivelant of
	tabSpaces = 4;

	//Prompt user for filename 
    printf("Please enter a filename: ");
	scanf("%s", fileName);	
	
	//Open stream to the file specified by user
	fp = fopen(fileName, "r");
	
	//Until EOF is encountered, take input and count words, whitespace, characters, digits and punctuation.
    while(c != EOF) {
		c = fgetc(fp);
		if (c == ' ' || c == '\n') {
			//increase blank counter
			charArray[0]++;
		}
		else if (c == '\t') {
			//increase blank counter
			charArray[0] = charArray[0] + tabSpaces;
		}
		else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
			//increase character counter
			charArray[1] = charArray[1]++;
			if (lastChar == ' ' || lastChar == '\n' || lastChar == '\t' || lastChar == 0) {
				//increase word counter
				charArray[4]++;
			}
		}
		else if ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~')) {
			//increase punctuation counter
			charArray[2] = charArray[2]++;
		}
		else if (c >= '0' && c <= '9') {
			//increase digit counter
			charArray[3] = charArray[3]++;
		}
		else {
			break;
		}
		//Keep track of last character for comparison. Used for word count.
		lastChar = c;
	}
	
	//Print output
	printf("\n\nNumber of words: %d\n\n", charArray[4]);
	printf("Number of blanks: %d\nNumber of letters: %d\nNumber of punctuation marks: %d\nNumber of digits: %d\n", charArray[0], charArray[1], charArray[2], charArray[3]);
	return 0;
}

The problem is I get a "bus error" when I run this code - this only started happening when I tried ot introduce the user prompt functionality. From my understanding this can be caused by some problem with allocating memory or accessing memory I shouldnt be... Is it something wrong with the fileName[] variable?

If anyone can point me in the right direction it would be appreciated, not looking for someone to solve for me though...

Cheers
ZipOn

IT Support Forum?

22 July 2010 - 09:34 AM

Hi guys, does anyone know of an active for discussion of IT support workers?

I currently am a few months into my first helpdesk job at 19 years old and have already put my years of uni level CS to good use and combined with the practical experience I have gained on the job. I'm comfortable with my work on the helpdesk, but would like to have a forum to frequent that is mainly for people in a similar job to share ideas etc.

Also, in a few months ive told im being promoted to desktop engineer, which would be dealing with a lot more hardware. I have limited experience dealing with the inner workings of the physical machine itself, (knwoledge mainly consists of the software aspect of CS, never even built my own machine). So if anyone knows of a forum for IT supporters (both software and hardware) it would be great to hear about it. Also, if anyone has nay advice on brushing up on common hardware issues in a professional environment (maybe a book or something) feel free to share.

Cheers

Zip

Question about Adium and groups of contacts

29 April 2010 - 04:54 PM

Hi guys quick question, does anyone know if theres a way to display a different user name to different groups on the same IM account? (I'm using Adium). Its just a trivial thing, i could easily just make a new account. Its just that Ive added a few people from codecall in their own Programming group and wanted to know if I could display my forum name and avatar for one group and my real name for my actual friends group. If not I suppose Ill just quickly make a second account and re-add anyone.

Cheers, -Zip

B-direction Unix Domain Sockets?

26 April 2010 - 08:31 PM

Hi, new to socket programming have been working through some exercises. I have little Perl knowledge and am piecing stuff together from tutorials etc I find online. Basically, I want to have a server and a client. The server opens and waits for connections, one client connects and sends a message to the server, the server sends a response to the client and then terminates the connection and waits for another. This is the code I've pieced together so far:

Server
#! usr/local/bin/perl -w
  2 
  3 use Socket;
  4 use FileHandle;
  5 
  6 #Create new socket filehandle SERVER which is
  7 #UNIX-domain and stream-based.
  8 socket (SERVER, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
  9 #
 10 autoflush SERVER 1;
 11 
 12 #bind SERVER socket filehandle to filename stored in $filename
 13 unlink "/tmp/mysock";
 14 bind(SERVER, sockaddr_un("/tmp/mysock")) or die "bind: $!";
 15 
 16 #Listen for connections. Integer in listen() specifies max number
 17 # of waiting connections that can be supported.
 18 listen (SERVER, 1) or die "listen: $!";
 19 
 20 for (;;) {
 21   accept(DATA, SERVER);
 22   print SERVER "Because you are a rude client!";
 23   # perform communication between client and server
 24   # reading and writing information to the DATA filehandle.
 25   print "Client says: ".<DATA>."\n";
 26   close DATA; # finished with this client 
 27   # go back to accept the next communication 
 28 }

Client
1 #! usr/local/bin/perl -w
  2 
  3 use Socket;
  4 use FileHandle;
  5 
  6 #Create socket called CLIENT 
  7 socket (CLIENT, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
  8 #Connect to server  
  9 connect(CLIENT, sockaddr_un("/tmp/mysock")) or die "connect: $!";
 10 autoflush CLIENT 1;
 11 
 12 print CLIENT "Why don't you ever pick up the phone?\n";
 13 print "Server says: ".<SERVER>."\n";

What happens now is, as far as I can see, the connections are all made, the client sends the server a message but then the server cannot respond. I get this error:

Name "main::SERVER" used only once: possible typo at client.pl line 13.
readline() on unopened filehandle SERVER at client.pl line 13.

Can anyone point out what it is I'm doing wrong here and give some suggestions?

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download