首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中K&R中的练习3-2 :将转义序列转换为可见序列

C中K&R中的练习3-2 :将转义序列转换为可见序列
EN

Stack Overflow用户
提问于 2014-09-11 06:17:41
回答 1查看 1.1K关注 0票数 0

K&R:练习3-2。编写一个转义( s,t)函数,将字符串t复制到s时,将换行符和制表符等字符转换为可见的转义序列,如\n和\t。也为另一个方向编写一个函数,将转义序列转换为真正的字符。

编辑:明白了!!谢谢!!是否需要添加ss_index = '\0'?看起来我的程序在没有它的情况下运行得很好(为什么呢?它不应该导致错误或内存问题吗)?ty再一次

我的问题是:我不确定我的算法是否在正确的道路上。有人能检查一下我下面的代码吗?它没有打印出任何可见的转义序列。我的想法是将从t扫描进来的每个\n或\t替换为\,然后是\n或a\,然后是t(在s数组中使用2个空格代替t中的每1个空格)。另外,有没有人知道我如何将'\n‘赋值给字符数组?例如,如果我输入"hi“,然后输入,如果我使用c=getchar(),它会将一个\n扫描到一个数组中。有没有其他方法可以让我在运行前手动输入'\n‘到数组中?非常感谢各位!任何帮助都是非常感谢的。

代码语言:javascript
复制
#include <stdio.h>

void escape(char s[], char t[]);

int main() {
    char s[50];
    char t[50] = "hello guys    bye test    bye\\n";
    escape(s, t);
    printf("%s\n", s);
}

void escape(char s[], char t[]) {
    int s_index = 0;
    int t_index = 0;
    while (t[t_index] != '\0') {
        switch (t[t_index]) {
            case ('\n'):
                s[s_index] = '\\';
                s[s_index + 1] = 'n';
                t_index++;
                s_index = s_index + 2;
                break;
            case ('\t'):
                s[s_index] = '\\';
                s[s_index + 1] = 't';
                t_index++;
                s_index = s_index + 2;
                break;
            default:
                s[s_index] = t[t_index];
                s_index++;
                t_index++;
                break;
        }
    }
    s[s_index] = '\0';
}
EN

回答 1

Stack Overflow用户

发布于 2015-01-06 15:15:50

我不确定我是否会过于热衷于从K&R学习C语言,这本书在当时是一本很棒的书,但现在有更好的书,而且语言也发生了很大的变化。

但是,至少,您应该转向有意义的变量名称,并学习如何重构公共代码,这样您就不会不必要地重复自己。

我将从以下几行代码开始执行此任务。它集中了常见的代码(在本例中作为宏,以简化代码),并且还防止了缓冲区溢出。首先是必需的头文件和帮助器宏:

代码语言:javascript
复制
#include <stdio.h>

// Macros for output of character sequences,
//  including buffer overflow detection.

// Output a single character.

#define OUT_NORM(p1) \
    if (sz < 1) return -1; \
    sz--; \
    *to++ = p1;

// Output a backslash followed by a single
//  character.

#define OUT_CTRL(p1) \
    if (sz < 2) return -1; \
    sz -= 2; \
    *to++ = '\\'; \
    *to++ = p1;

然后是函数本身,通过使用公共代码大大简化,并且对缓冲区溢出免疫:

代码语言:javascript
复制
static int escape (char *from, char *to, size_t sz) {
    // Process every character in source string.

    while (*from != '\0') {
        // Output control or normal character.

        switch (*from) {
            case '\n': OUT_CTRL ('n'); break;
            case '\t': OUT_CTRL ('t'); break;
            default:   OUT_NORM (*from);
        }
        from++;
    }

    // Finish off string.

    OUT_NORM ('\0');

    return 0;
}

最后,还有一个测试程序,用于检查:

代码语言:javascript
复制
int main (void) {
    char src[] = "Today is a good\n\tday to die.\n";
    char dest[100];

    printf ("Original: [%s]\n", src);

    if (escape (src, dest, sizeof(dest)) != 0)
        puts ("Error found");
    else
        printf ("Final: [%s]\n", dest);

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25775987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档