Skip to content

Instantly share code, notes, and snippets.

@lleaff
Created February 9, 2017 13:21
Show Gist options
  • Save lleaff/c4964c93762d7238eb3c8dd0518b2cc7 to your computer and use it in GitHub Desktop.
Save lleaff/c4964c93762d7238eb3c8dd0518b2cc7 to your computer and use it in GitHub Desktop.
C89: Read number from stdin and reformat
/*
* Compile:
* gcc -Wall -Werror -pedantic -ansi -std=c89 readnum.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_INPUT_LEN 1000
#define PRECISION 2
int is_digit(char c) {
return c >= '0' && c <= '9';
}
int string_is_float(char s[]) {
unsigned int i;
if (!s[0]) /* Length */
return (0);
for (i = 0; s[i] && (s[i] == '-' || s[i] == '+'); ++i) ;
for (; s[i] && is_digit(s[i]); ++i) ;
if (!s[i])
return (i);
if (s[i++] != '.')
return (0);
for (; s[i] && is_digit(s[i]); ++i) ;
return !s[i] ? i : 0;
}
char *format_float_input(char s[], unsigned int precision)
{
unsigned int i;
unsigned int j;
int sign;
int len;
char *fmtd;
char *res;
if (!(len = string_is_float(s)))
return (NULL);
res = fmtd = malloc(sizeof(char) * len);
sign = 1;
for (i = 0; i < len && (s[i] == '-' || s[i] == '+'); ++i)
sign *= s[i] == '-' ? -1 : 1;
if (sign == -1)
*fmtd++ = '-';
for (; i < len && is_digit(s[i]); ++i)
*fmtd++ = s[i];
if (i++ == 0)
*fmtd++ = '0';
*fmtd++ = '.';
for (j = 0; j < 2; ++i, ++j)
*fmtd++ = (i < len ? s[i] : '0');
*fmtd = '\0';
return res;
}
int main() {
char input[MAX_INPUT_LEN];
char *fmtd;
printf("Input a number (\"q\" to quit):\n");
while (1)
{
printf("> ");
fgets(input, MAX_INPUT_LEN, stdin);
input[strcspn(input, "\n")] = '\0';
if (!*input || !strcmp(input, "q"))
break;
fmtd = format_float_input(input, PRECISION);
printf("%s\n", fmtd ? fmtd : "Invalid number!");
free(fmtd);
}
return fmtd ? 0 : 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment