k&r section 5.5 excercise solutions

master
Tibor Bizjak 2023-07-18 16:43:22 +02:00
parent e6de3d1193
commit ee59768555
4 changed files with 226 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}