Recognizing that there's a better way than trial & error is the first step.
I usually start with paper & pencil. I get a rough sense of what the client's asking for and sketch out the User Experience. I need to know what the user needs to see, what they need to do, etc. For larger projects, this would evolve into Requirements docs, Functional specifications, a Vision, etc. I'd also identify user stories on a per-Role basis.
My next step is to look at where the data comes from, how I'm going to store it, what manipulations (if any) I need to do on it, etc. This includes both in-memory storage and database (not every program requires a database). Data structures are your friend. Picking the right data organization will make the difference between a program that's a joy to use & one that's barely tolerable.
Program organization comes next - what objects do I have, how do they communicate, how do I segregate functionality so I separate stuff that changes from stuff that doesn't, how do I keep things DRY, etc.
There are some canned designs (such as model-view-controller) that can be useful. The trick is knowing when the designs are appropriate and when they aren't so you don't suffer from hammer syndrome.
Right before I start coding I take a final look at my plan and look for things to remove. There's a term for this -- "YAGNI". Also, remember - you don't have to fix any features you leave out.
At this point I have the start of a plan - when I sit down at the keyboard I have an idea of what I'm trying to accomplish.
You might also want to read up on Test Driven Development - it's a very good technique, but not by itself an answer to your question.