Skip to content

Commit

Permalink
<Libc> Add support for scanf to accept formatted
Browse files Browse the repository at this point in the history
input

modified:   src/lib/libc/include/stdio.h
modified:   src/lib/libc/scanf.c

- Support for int, char, string, float format specifiers added for scanf
- Added gets function to accept string with spaces

Issue: #225
  • Loading branch information
sagarladla committed May 25, 2024
1 parent 35b69a7 commit 9ad418a
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/lib/libc/include/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ int fputc(const FILE *, const char);
int fgetc(const FILE *, char *);
char getch();
char getchar();
char *gets();
int scanf(const char * restrict, ...);

#ifdef _STDBOOL_H_
int fprintf(const FILE *, bool, const char *fmt, ...);
Expand Down
156 changes: 156 additions & 0 deletions src/lib/libc/scanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include <ccpfs.h>
#include <stdio.h>
#include <stddev.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>

int fgetc(const FILE *dev, char *c)
{
Expand Down Expand Up @@ -42,3 +45,156 @@ char getchar()
} while(temp != '\r');
return c;
}

/**
* get string with spaces
*
* @brief This function will take string input with spaces
*
*/
char *gets()
{
char *s = (char *)malloc(sizeof(char)), temp;
int i = 0;
do
{
temp = getch();
fputc(stdout, temp);
if(temp == '\r')
{
fputc(stdout, '\n');
}
else
{
s[i++] = temp;
}
} while(temp != '\r');
return s;
}

/**
* scanf
*
* @brief This function will take standard input for default data types.
* input will break at spaces
*
*/

#define CURRCHAR (temp)
#define CHARIN() (temp = getch())
int scanf(const char * restrict fmt, ...)
{
unsigned int count = 0;
char c = '0', temp;
va_list ap;
va_start(ap, fmt);
while (*fmt)
{
if (*fmt == '%')
{
fmt++;
/* char length : %7d */
unsigned int cl = 0;
while (isDigit(*fmt))
{
cl *= 10;
cl += *fmt++ - '0';
}
switch (*fmt++)
{
case 'c':
{
/* skip leading spaces */
while (isSpace(CHARIN()))
{
if (CURRCHAR == '\r')
fputc(stdout, '\n');
else
fputc(stdout, CURRCHAR);
}
fputc(stdout, CURRCHAR);
c = CURRCHAR;
while (CHARIN())
{
fputc(stdout, CURRCHAR);
if (isSpace(CURRCHAR))
break;
}
fputc(stdout, '\n');
*(char *)va_arg(ap, char *) = c;
count++;
break;
}
case 's':
{
char *s = va_arg(ap, char *);
/* skip leading spaces */
while (isSpace(CHARIN()))
{
if (CURRCHAR == '\r')
fputc(stdout, '\n');
else
fputc(stdout, CURRCHAR);
}
fputc(stdout, CURRCHAR);
*s++ = CURRCHAR;
while (CHARIN())
{
fputc(stdout, CURRCHAR);
if (isSpace(CURRCHAR))
break;
*s++ = CURRCHAR;
}
fputc(stdout, '\n');
*s = '\0';
count++;
break;
}
case 'u':
case 'd':
{
int a = 0;
/* skip leading spaces */
while (isSpace(CHARIN()))
{
if (CURRCHAR == '\r')
fputc(stdout, '\n');
else
fputc(stdout, CURRCHAR);
}
fputc(stdout, CURRCHAR);
c = CURRCHAR;
while (CHARIN())
{
a *= 10;
if (isDigit(c))
a += (c - '0');
else
a += (int)c;
if (isSpace(CURRCHAR))
break;
c = CURRCHAR;
fputc(stdout, CURRCHAR);
}
fputc(stdout, '\n');
*(int *)va_arg(ap, int *) = a;
count++;
break;
}
case 'f':
{
char *a = gets();
*(float *)va_arg(ap, float *) = (float)atof(a);
count++;
break;
}
default:
break;
}
continue;
}
/* increment pointer if % not found */
fmt++;
}
return count;
}

0 comments on commit 9ad418a

Please sign in to comment.