Contact Bounce
This is known as contact bounce and happens when the metal contacts in the button or switch bounce against each other when you push it. The microcontroller is fast enough to pick up these bounces and, as far as it's concerned, you're toggling the switch many times in as much as 10 milliseconds of time.
Different switches and buttons will have a different amount of contact bounce, and even one switch will behave differently between two presses.
Here's a button press captured on a scope (image from Maxim):

At 2ms/div we don't see a stable signal until 6ms after initial contact!
Solutions
Add a delay
The absolute simplest solution is to introduce a short delay after you read the button input. This will prevent the code from picking up any bounces and when it resumes, the signal should be stable.
if (digitalRead(A3) == 0) {
// do something here
delay(500);
}
In the example above, I delay 500ms after reading the state of the pin. The button is normally high so when I press it down, the state of the pin goes to logic 0. I pick that up in the code and do something and then wait at least 500ms before continuing.
Obviously, this code will just halt for half a second every time you push a button, which may or may not be acceptable in your application. You can decrease the amount of delay depending on the contact bounce time of your switch, too, but I play it safe here.
Ignore button presses too close to each other
Similar to the solution above but instead of adding a hard delay, you use the millis()
function to keep track of when the last time the switch was triggered. Every time you see a switch trigger, you compare against the time and, if not enough time has elapsed (say like 500ms in my previous example), you ignore it.
This solves the problem of having to use delay()
in your code.
Switch debouncer IC
There are things like the MAX6816 which is an IC that you put in between your switch and microcontroller input. It will denounce the signal for you. At a price of $1.62 @1k you'll probably never use this.
Other
There are many solutions to this problem... I always do it in software, but some others include using a latch or capacitor.
Debounce Code – one post to rule them all