I have put together this program that seems to do what I want without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine. Does
anyone see what's wrong ? I have a c99 compiler. Thanks.
#include <stdio.h>
#include <stdlib.h>
int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}
fp=fopen( "data", "a");
ftell(fp);
fseek(fp,sizeof(double),SEEK_CUR);
fprintf(fp,"%.2f\n",x);
fclose(fp);
}
While the advice to use a debugger is good advice, the entire solution
to this problem can be found via static analysis. Splint is free:
http://www.splint.org
Here is the analysis using splint and pc-lint:
#include <stdio.h>
#include <stdlib.h>
int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}
fp=fopen( "data", "a");
ftell(fp);
fseek(fp,sizeof(double),SEEK_CUR);
fprintf(fp,"%.2f\n",x);
fclose(fp);
}
/*
Splint output:
==============
C:\tmp>splint bug.c
Splint 3.1.1 --- 12 Mar 2007
bug.c: (in function main)
bug.c(13,11): Possibly null storage fp passed as non-null param: ftell
(fp)
A possibly null pointer is passed as a parameter corresponding to a
formal
parameter with no /*@null@*/ annotation. If NULL may be used for
this
parameter, add a /*@null@*/ annotation to the function parameter
declaration.
(Use -nullpass to inhibit warning)
bug.c(12,8): Storage fp may become null
bug.c(13,5): Return value (type long int) ignored: ftell(fp)
Result returned by function call is not used. If this is intended,
can cast
result to (void) to eliminate message. (Use -retvalother to inhibit
warning)
bug.c(14,29): Function fseek expects arg 2 to be long int gets size_t:
sizeof(double)
To allow arbitrary integral types to match long unsigned, use
+longintegral.
bug.c(14,5): Return value (type int) ignored: fseek(fp, sizeof...
Result returned by function call is not used. If this is intended,
can cast
result to (void) to eliminate message. (Use -retvalint to inhibit
warning)
bug.c(16,5): Return value (type int) ignored: fclose(fp)
bug.c(17,2): Path with no return in function declared to return int
There is a path through a function declared to return a value on
which there
is no return statement. This means the execution may fall through
without
returning a meaningful result to the caller. (Use -noret to inhibit
warning)
Finished checking --- 6 code warnings
Lint output:
============
C:\tmp>"C:\Lint\Lint-nt" +v -i"C:\Lint" std.lnt -os(_LINT.TMP)
bug.c
PC-lint for C/C++ (NT) Vers. 8.00u, Copyright Gimpel Software
1985-2006
--- Module: bug.c (C)
C:\tmp>type _LINT.TMP | more
--- Module: bug.c (C)
_
ftell(fp);
bug.c(13) : Warning 534: Ignoring return value of function
'ftell(struct _iobuf
*)' (compare with line 257, file C:\Program Files\Microsoft Visual
Studio
8\VC\INCLUDE\stdio.h)
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\stdio.h(257) :
Info 830:
Location cited in prior message
_
ftell(fp);
bug.c(13) : Warning 668: Possibly passing a null pointer to function
'ftell(struct _iobuf *)', arg. no. 1 [Reference: file bug.c: line
12]
bug.c(12) : Info 831: Reference cited in prior message
_
}
bug.c(17) : Warning 533: function 'main(int, char **)' should return a
value
(see line 4)
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Note 952: Parameter 'argv' (line 4) could be declared
const ---
Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Info 818: Pointer parameter 'argv' (line 4) could be
declared as
pointing to const --- Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Note 952: Parameter 'argc' (line 4) could be declared
const ---
Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message
*/
A few minutes with Splint or PC-Lint and a C book can tell you exactly
what is wrong.
It will also behoove you to learn how to use a debugger. It is a very
bad idea to try to program by the seat of your pants (meaning making
*guesses* about what various program constructs are supposed to be
doing). If you learn the correct meanings of the language constructs
and also how to use tools at your disposal then you can learn to be an
effective programmer. If you do not learn these things then you will
never learn to be an effective programmer. It is not difficult to do
it, though it can be a bit tedious.