k&r section 5.5 excercise solutions
parent
e6de3d1193
commit
ee59768555
|
@ -0,0 +1,101 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
int getint(int *p);
|
||||
int getfloat(float *p);
|
||||
|
||||
/* ungetchar: push char c back to input stream */
|
||||
#define ungetchar(c) ungetc(c, stdin)
|
||||
|
||||
|
||||
/* tests getfloat, prints input to output, puts valid numbers
|
||||
* in brackets : n -> [n] */
|
||||
int main()
|
||||
{
|
||||
float x;
|
||||
int r;
|
||||
while ((r = getfloat(&x)) != EOF)
|
||||
if (!r) {
|
||||
int c;
|
||||
putchar(getchar());
|
||||
while (!isdigit(c = getchar()) && c != EOF && c != '-' && c != '+')
|
||||
putchar(c);
|
||||
ungetchar(c);
|
||||
} else
|
||||
printf("[%g]", x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we assert that EOF is negative */
|
||||
static_assert(EOF < 0, "EOF is not a negative number");
|
||||
|
||||
/* ugetint: gets unsigned int from input to n
|
||||
* n must be intialized by caller
|
||||
* takes optional arguments for loop increment
|
||||
* last char read is stored in varvar_c */
|
||||
#define ugetint(var_c, n, ...) \
|
||||
do { \
|
||||
for (; isdigit(var_c = getchar()); __VA_ARGS__) \
|
||||
n = 10 * (n) + var_c - '0'; \
|
||||
} while (0)
|
||||
|
||||
/* getint : gets int from input and overwrites it to p
|
||||
* returns 1 on valid integer, 0 if no integer is found
|
||||
* and EOF on EOF. */
|
||||
int getint(int *p)
|
||||
{
|
||||
int c;
|
||||
if ((c = getchar()) == EOF)
|
||||
return EOF;
|
||||
|
||||
/* handle sign */
|
||||
int sign = (c == '-') ? -1 : ((c == '+') ? 1 : 0);
|
||||
if (sign)
|
||||
c = getchar();
|
||||
if (!isdigit(c)) { /* not a number */
|
||||
ungetchar(c);
|
||||
if (sign)
|
||||
ungetchar((sign > 0) ? '+' : '-');
|
||||
return 0;
|
||||
}
|
||||
|
||||
*p = c - '0';
|
||||
ugetint(c, *p);
|
||||
ungetchar(c);
|
||||
*p *= (sign) ? sign : 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define DEC_SEP X('.') X(',')
|
||||
#define EXP_SEP X('e') X('E')
|
||||
|
||||
/* getfloat : gets float from input and overwrites it to p
|
||||
* returns 1 on valid integer, 0 if no integer is found
|
||||
* and EOF on EOF. */
|
||||
int getfloat(float *p)
|
||||
{
|
||||
char flag;
|
||||
int n;
|
||||
if ((flag = getint(&n)) < 1) /* not a number */
|
||||
return flag;
|
||||
*p = n;
|
||||
|
||||
int exp, c = getchar();
|
||||
/* fractional part */
|
||||
#define X(C) c == C ||
|
||||
if (DEC_SEP 0) {
|
||||
n = exp = 0;
|
||||
ugetint(c, n, exp--);
|
||||
*p += n * pow(10, exp);
|
||||
}
|
||||
#undef X
|
||||
/* exponent part */
|
||||
#define X(C) c == C ||
|
||||
if ((EXP_SEP 0) && getint(&exp)) {
|
||||
*p *= pow(10, exp);
|
||||
} else
|
||||
ungetchar(c);
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#include <stdio.h>
|
||||
|
||||
char *strcat(char *s, const char *t);
|
||||
char *strcpy(char *t, const char *s);
|
||||
size_t strlen(const char *s);
|
||||
|
||||
/* passes args to strcat, prints result */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
return 1;
|
||||
char s[strlen(argv[1]) + strlen(argv[2])];
|
||||
strcat(strcpy(s, argv[1]), argv[2]);
|
||||
printf("%s\n", s);
|
||||
}
|
||||
|
||||
/* strcat: concat string t to end of string s */
|
||||
char *strcat(char *s, const char *t)
|
||||
{
|
||||
int slen = strlen(s);
|
||||
return strcpy(s + slen, t) - slen;
|
||||
}
|
||||
|
||||
/* strcpy: copy string s to t */
|
||||
char *strcpy(char *t, const char *s)
|
||||
{
|
||||
char *tc = t;
|
||||
while ((*t++ = *s++))
|
||||
;
|
||||
return tc;
|
||||
}
|
||||
|
||||
/* strlen: return length of string s (without \0) */
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *sc = s;
|
||||
while (*s++)
|
||||
;
|
||||
return s - sc - 1;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int strend(const char *s, const char *t);
|
||||
|
||||
/* passes args to strend, prints result */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
return 1;
|
||||
printf("%s\n", (strend(argv[1], argv[2])) ? "true" : "false");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* strend: returns 1 if t == end of s otherwise false */
|
||||
int strend(const char *s, const char *t)
|
||||
{
|
||||
size_t s_len = strlen(s);
|
||||
size_t t_len = strlen(t);
|
||||
return (s_len >= t_len) && !strcmp(s + s_len - t_len, t);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *strncpy(char *t, const char *s, size_t n);
|
||||
char *strncat(char *t, const char *s, size_t n);
|
||||
int strncmp(const char *s, const char *t, size_t n);
|
||||
|
||||
/* strlen: returns string length (w/o '\0') */
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char * const sc = s;
|
||||
while (*s++)
|
||||
;
|
||||
return s - sc - 1;
|
||||
}
|
||||
|
||||
/* takes args s1, s2, n and passes them to the above declared
|
||||
* functions, prints the results */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 4)
|
||||
return 1;
|
||||
|
||||
int n = atoi(argv[3]);
|
||||
char s[strlen(argv[1]) + strlen(argv[2]) + 1];
|
||||
/* strncpy */
|
||||
printf("strncpy: %s\n", strncpy(s, argv[1], n));
|
||||
/* strncat */
|
||||
printf("strncat: %s\n", strncat(s, argv[2], n));
|
||||
/* strncmp */
|
||||
int comp = strncmp(argv[1], argv[2], n);
|
||||
printf("strncmp: %.*s ", n, argv[1]);
|
||||
putchar((comp > 0) ? '>' : (comp < 0) ? '<' : '=');
|
||||
printf(" %.*s\n", n, argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* strncpy: copies at most n chars from s to t, returns t*/
|
||||
char *strncpy(char *t, const char *s, size_t n)
|
||||
{
|
||||
char * const tc = t;
|
||||
while (n-- && (*t++ = *s++))
|
||||
;
|
||||
*t = '\0';
|
||||
return tc;
|
||||
}
|
||||
|
||||
/* strncat: concats at most n chars of s to t, returns t */
|
||||
char *strncat(char *t, const char *s, size_t n)
|
||||
{
|
||||
strncpy(t + strlen(t), s, n);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* strncmp: compares at most n chars of s and t */
|
||||
int strncmp(const char *s, const char *t, size_t n)
|
||||
{
|
||||
if (!n)
|
||||
return 0;
|
||||
while (--n && *s && (*s == *t))
|
||||
s++, t++;
|
||||
return *s - *t;
|
||||
}
|
Loading…
Reference in New Issue