Now I'm only testing numbers like 0.05.
Code:
#include "../Headers/conversion.h"
#include <stdlib.h>
void itoa(int n, char* s)
{
int sign, i;
i = 0;
if( (sign = n) < 0) /* record sign */
n = -n; /* turn n positive */
do {
s[i++] = abs(n % 10) + '0';
} while( (n /= 10) > 0);
if(sign < 0)
{
s[i++] = '-';
}
s[i] = '\0';
}
Code:
#include <ctype.h>
#include "../Headers/validation.h"
int isanumber(char* s) {
int i = 0;
while(s[i] != '\n')
{
if(isalpha((unsigned char) s[i]) || isblank( (unsigned char) s[i]) )
break;
i++;
}
if(s[i] == '\n')
return 1;
return 0;
}
Code:
#include <string.h>
#include "../Headers/strings.h"
void reverse(char* s, char* reversed)
{
int i, j;
for(i = strlen(s) - 1, j = 0; i >= 0; i--, j++)
reversed[j] = s[i];
reversed[j] = '\0';
}
Code:
#include <ctype.h>
#include <string.h>
#include "../Headers/conversion.h"
#include "../Headers/strings.h"
#ifndef MAXSIZE
#define MAXSIZE 1000
#endif
/* atof: convert string s in scientific notation double */
char* Atof(char* s)
{
double val, power;
int i, sign, dotLocation, nPlaces;
char* notation;
/* (itoa returns the string from the end to the beginning, i.e. inverted) */
char revstrval[MAXSIZE];
char revstrnplaces[MAXSIZE];
/* the correct order of the string representation of the numbers */
char straightstrval[MAXSIZE];
char straightstrnplaces[MAXSIZE];
dotLocation = nPlaces = 0;
/* first part: get a double from the string */
/* while there is a space, keep iterating */
for(i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-') ? -1 : 1;
/* if there is a sign inside the array, just ignore it */
if(s[i] == '+' || s[i] == '-')
i++;
/* the next block converts the string to a double with the proper sign */
/* ------------------------------------------------- */
for(val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if(s[i] == '.')
{
dotLocation = i;
i++;
}
for(power = 1.0; isdigit(s[i]); i++)
{
val = 10.0 * val + (s[i] - '0');
power *= 10.0;
}
val = sign * val / power;
/* ------------------------------------------------- */
/* second part: write double in scientific notation */
/* count the number of places starting from the first digit after the dot */
for(i = s[dotLocation] + 1; s[i] != '\0'; i++)
nPlaces++;
/* verify if first digit is zero and make sure there is, at least, one
* place (for numbers like 0.05) */
if(val / 1 == 0 && power > 1.0)
{
val *= power;
itoa(val, revstrval);
itoa(nPlaces, revstrnplaces);
reverse(revstrval, straightstrval);
reverse(revstrnplaces, straightstrnplaces);
notation = strcat(straightstrval, "e-");
notation = strncat(notation, straightstrnplaces, MAXSIZE);
}
/* verify if first digit is different from zero and make sure there is, at least, one
* place (for numbers like 125.5) */
else {
}
return notation;
}
Code:
#include <stdio.h>
#include <string.h>
#include "Headers/conversion.h"
#include "Headers/validation.h"
#ifndef MAXSIZE
#define MAXSIZE 1000
#endif
int main(void)
{
char strnum[MAXSIZE];
char notation[MAXSIZE];
do {
printf("Please enter a double: ");
fgets(strnum, sizeof(strnum), stdin);
}while(!isanumber(strnum));
strcpy(notation, Atof(strnum));
printf("The double value in scientific notation is %s\n", notation);
return 0;
}
Code:
gcc -g -Wall mainatof.c Conversion/atof.c Strings/reverse.c Conversion/itoa.c Validation/isanumber.c -o mainatof
./mainatof
Please enter a double: 0.05
Segmentation fault
Code:
valgrind --tool=memcheck --leak-check=full ./mainatof
==5566== Memcheck, a memory error detector
==5566== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==5566== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==5566== Command: ./mainatof
==5566==
Please enter a double: 0.05
==5566== Conditional jump or move depends on uninitialised value(s)
==5566== at 0x400A3C: Atof (atof.c:64)
==5566== by 0x40075F: main (mainatof.c:21)
==5566==
==5566== Use of uninitialised value of size 8
==5566== at 0x4C2D007: strcpy (mc_replace_strmem.c:438)
==5566== by 0x400774: main (mainatof.c:21)
==5566==
==5566== Invalid read of size 1
==5566== at 0x4C2D007: strcpy (mc_replace_strmem.c:438)
==5566== by 0x400774: main (mainatof.c:21)
==5566== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5566==
==5566==
==5566== Process terminating with default action of signal 11 (SIGSEGV)
==5566== Access not within mapped region at address 0x0
==5566== at 0x4C2D007: strcpy (mc_replace_strmem.c:438)
==5566== by 0x400774: main (mainatof.c:21)
==5566== If you believe this happened as a result of a stack
==5566== overflow in your program's main thread (unlikely but
==5566== possible), you can try to increase the size of the
==5566== main thread stack using the --main-stacksize= flag.
==5566== The main thread stack size used in this run was 8388608.
==5566==
==5566== HEAP SUMMARY:
==5566== in use at exit: 0 bytes in 0 blocks
==5566== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5566==
==5566== All heap blocks were freed -- no leaks are possible
==5566==
==5566== For counts of detected and suppressed errors, rerun with: -v
==5566== Use --track-origins=yes to see where uninitialised values come from
==5566== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault