c - C : convert escape sequences into visible ones 的 K&R 中的练习 3-2

标签 c string tabs character newline

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

编辑:明白了!!谢谢!!我需要添加 s[s_index] = '\0' 吗?看来我的程序没有它就可以正常工作(为什么?它不会导致错误或内存问题)吗?再次打字

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

#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';
}

最佳答案

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

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

我将开始执行此任务的代码如下所示。它具有集中的公共(public)代码(在本例中为宏,以简化代码),并且还可以防止缓冲区溢出。首先是必需的 header 和辅助宏:

#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;

然后是函数本身,通过使用通用代码大大简化,并且不受缓冲区溢出的影响:

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

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

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

关于c - C : convert escape sequences into visible ones 的 K&R 中的练习 3-2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25775987/

相关文章:

在 C 中比较字符串数组

java - 在java中将字符串写入rtf不会保留结构

mysql - Doctrine 2 DQL CONCAT 字段和常量字符串

Jquery UI 选项卡小部件 - Href 和 aria-controls

检查文件是否存在于 C 中

c - 如果定义 float ,是否需要指定 x.yf?

c - C 中的全局静态变量和局部静态变量如何不会发生冲突

c - 在数组中读取迷宫文件的数组,立方体大小不均,多余字符

ios - 选项卡栏快速选择索引

jquery - 选项卡上的引导预加载器