K&R学习笔记:第3章习题

3-2 编写一个函数escape(s,t), 将字符串t复制到s中,并在替换的过程中把制表符,换行符替换成\n,\t相应的可见转义字符。要求使用switch语句。再编写一个相反功能的函数,将转义字符替换成实际的字符。

#include <stdio.h>
#define MAXSIZE    1000
char s1[MAXSIZE];
char s2[MAXSIZE]; 

void escape(char *s1 , char *s2);

int main()
{
    extern char s1[MAXSIZE], S2[MAXSIZE];
    int c, i;
    i = 0;
    while((c = getchar()) != EOF && i < MAXSIZE)
        s2[i++] = c;
    s2[i] = '\0';
    escape(s1, s2);
    printf("%s\n", s2);
    printf("%s\n", s1);
    return 0;
}

void escape(char *s1 , char *s2)
{
    int c, i, j;
    i = j = 0;
    for(; (c = s2[i]) != '\0'; ++i) {
        switch (c) {
            case '\t':
                s1[j++] = '\\';
                s1[j++] = 't';
                break;
            case '\n':
                s1[j++] = '\\';
                s1[j++] = 'n';
                break;
            default:
                s1[j++] = s2[i];
                break;
        }
    }
    s1[j] = '\0';
}
#include <stdio.h>
#define MAXSIZE    1000
void unescape(char *s, char *t);

char s1[MAXSIZE];
char s2[MAXSIZE];

int main()
{
    int i, c;
    for (i = 0; i < MAXSIZE && (c = getchar()) != EOF; ++i)
        s1[i] = c;
    s1[i] = '\0';
    unescape(s2, s1);
    printf("%s\n", s2);
    return 0;
}

void unescape(char *s, char *t)
{
    int i, j;
    for (j = i = 0; t[i] != '\0'; ++i) {
        switch (t[i]) {
            case '\\':
                switch (t[++i]) {
                    case 'n':
                        s[j++] = '\n';
                        break;
                    case 't':
                        s[j++] = '\t';
                        break;
                    default:
                        s[j++] = '\\';
                        s[j++] = t[i];
                        break;
                }
                break;
            default:
                s[j++] = t[i];
                break;
        }
    }
    s[j] = '\0';
}

3-3 编写函数expand(s1, s2), 将字符串中s1类似与a-z一类的速记符号在字符串s2中扩展成等价的完整列表abc...xyz。该函数可以处理大小写字母和数字, 并可以处理a-b-c, a-z0-9, -a-z等类似情况。 作为前导和尾随的-字符原样排印。

#include <stdio.h>

void expand(char *s1, char *s2);

char dst[100];
char src[100] =  {'-', 'a', '-', 'b', '-', 'c', '0', '-', '9', '-'} ;

int main()
{
    expand(src, dst);
    printf("%s\n", dst);
    return 0;
}

void expand(char *s1, char *s2)
{
    int c, i, j;
    i = j = 0;
    while ((c = s1[i++]) != '\0') {
        if (s1[i] == '-' && s1[i+1] > c) {
                while (c < s1[i+1])
                    s2[j++] = c++;
                ++i;
        } else
            s2[j++] = c;
    }
    s2[j] = '\0';
}

3-4 在对数的对二补码表示中, 我们编写的itoa函数不能处理最大的负数,即n为-2^(字长-1) 的情况。 修改函数,使它在任何机器上运行时都能正确打印。

注意:1)最大负数取负之后还是本身。2)负数的余数还是负数。

#include <stdio.h>
#include <string.h>

#define abs(x)    ((x) > 0 ? (x) : -(x))

char s[100];

void itoa_new(int n, char *s);
void reverse_new(char *s);

int main()
{
    extern char s[100];
    itoa_new(1<<31, s);
    printf("%s\n", s);
    return 0;
}

void itoa_new(int n, char *s)
{
    int i, sign;
    sign = n;
    i = 0;
    do {
        s[i++] = abs(n % 10) + '0';
    } while((n /= 10) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse_new(s);
}

void reverse_new(char *s)
{
    int i, j;
    char tmp;
    for (i = 0, j = strlen(s)-1; i < j; i++, j-- ) {
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

3-5 编写itob(n,s,b), 将整数n 转化成以b为底的数,并将转化结果以字符的形式保存到字符串s中。

#include <stdio.h>
#include <string.h>

void itob(int n, char *s, unsigned b);
void reverse(char *s);

char s[100];

int main()
{
    itob(256, s, 2);
    printf("%s\n", s);
    return 0;
}

void itob(int n, char *s, unsigned b)
{
    unsigned un = (unsigned)n;
    unsigned m,i;
    i = 0;
    do {
        m = un % b;
        s[i++] = (m > 9) ? (m - 10 + 'a'): (m + '0');
    } while ((un /= b) > 0);
    s[i] = '\0';
    reverse(s);
}

void reverse(char *s)
{
    int i, j;
    char tmp;
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}    

3-5 修改itoa函数,是该函数可以接受3个参数,其中第三个参数为宽度。 当转换结果小于给定宽度的时候,可以用空格填充。

扫描二维码关注公众号,回复: 2506598 查看本文章
#include <stdio.h>
#include <string.h>

#define abs(x)    ((x) > 0 ? (x) : -(x))

char s[100];

void itoa_new(int n, char *s, int w);
void reverse_new(char *s);

int main()
{
    extern char s[100];
    itoa_new(1<<31, s, 32);
    printf("%s\n", s);
    return 0;
}

void itoa_new(int n, char *s, int w)
{
    int i, sign, count;
    sign = n;
    i = 0;
    count = 0;
    do {
        s[i++] = abs(n % 10) + '0';
        ++count;
    } while((n /= 10) != 0);
    if (sign < 0) {
        s[i++] = '-';
        ++count;
    }
    while (count < w) {
        s[i++] = ' ';
        ++count;
    }
    s[i] = '\0';
    reverse_new(s);
}

void reverse_new(char *s)
{
    int i, j;
    char tmp;
    for (i = 0, j = strlen(s)-1; i < j; i++, j-- ) {
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

猜你喜欢

转载自www.cnblogs.com/chritran-dlay/p/9337882.html