M
Mike Wahler
hokiegal99 said:Hi Guys,
This is my first C program. I started programming in Python. Please look
over this source and let me know if I'm doing anything wrong. I want to
start out right with C, so if you see anything wrong tell me now while I
am learning!
Thou hast already committed thy first sin, my son.
The first C program one should write is the classic
"Hello world".
But let's take a look.
First, if you share code here, if at all possible post
*compilable* code. Of course the fastest way for anyone
to spot any syntax errors is to paste your code into a
compiler and compile it. This I did, but first I had
to spend time deleting all those > characters. Actually,
their presence makes me suspect you copied that out of
a newsgroup post or email message.
Also, learn to indent your code. What does the example
code in your textbook look like? Is it all left aligned
like that? Which textbook(s) are you reading?
range */Thanks !!!
1. Those comments are worse than useless. They only clutter
the code and give no additional information. The identifier
names you're using (which are pretty good ones btw) already
convey the information in the comments (except the 'IP' part)
If I commented this part at all, I'd write something like:
/* IP address octets */
int octet0;
int octet1;
int octet2;
int octet3;
Actually I'd put these values in an array, but you're probably
not that far with the language yet.
2. There's no reason to put these at file scope. They should
go inside your 'main()' function, where they're used.
range to */
Another useless comment. Your (again good) identifier name
'outputFile' tells the story : it's an output file. If you
want to convey that the file will contain 'IP addresses',
perhaps a name like 'IPFileOut' or similar might be closer.
This object should also be defined inside your 'main()'
function, not here.
main() */
Correct. Though preferred would be
int main(void)
More useless comments.
Also, these values could be specified at definition time
with initializers (these definitions should be inside
this function anyway):
int octet0 = 192;
int octet1 = 168;
int octet2 = 1;
int octet3 = 0;
/* technically initialization of 'octet3' is not necessary,
since you assign it a value below before using it. But
I find that *always* initializing *every* object with
*some* valid value is a good defensive practice. If
you don't give an initial value, and forget to do so
before trying to access it, you get 'undefined behavior.'
Not Good(tm) */
write mode */
There's no standard 'open mode' of "wt". C streams are
'text mode' by default, unless otherwise specified.
Just use "w".
Also, very important is that you check that the call to
'fopen()' succeeded before trying to touch the file.
If 'fopen()' failed, any attempts at i/o result in,
you guessed it, undefined behavior.
if(outputFile == NULL)
{
puts("Cannot open input");
return EXIT_FAILURE; /* 'EXIT_FAILURE' needs #include <stdlib.h>
}
}
This will iterate for values of 'octet3' of 1 through
254 inclusive. If you want to include 255, change the
< to <= or compare against 256 with <. I also see you
start with 1 and not zero. This range of values may be
what you want, I don't know. Just drawing attention to
it just in case.
octet3);
You need to check that 'fprintf()' succeeded here.
See your compiler manual or textbook to find out how.
Nitpick: This is valid, but the parentheses are not
needed. 'return' is not a function, it's a keyword.
All in all, not bad. But again, you first should have
written the "Hello world" program. Now go forth and
sin no more.
-Mike