【问题标题】:The C Programming Language, Ch.1 Exercise 1.10 (Getchar and Putchar)C 编程语言,第 1 章练习 1.10(Getchar 和 Putchar)
【发布时间】:2014-04-07 04:05:57
【问题描述】:

我已经为此工作了 2 个小时,但我被卡住了...我在网上找到了答案,但这并不能帮助我了解我显然遗漏的概念。

提示:编写一个程序,将其输入复制到其输出,将每个制表符替换为 \t ,将每个退格替换为 \b ,将每个反斜杠替换为 \\ 。这使得制表符和退格键以明确的方式可见。

这就是我想出的,它不会用指定的putchar 替换tab\,它只是将它添加到它的前面。(我没有退格,因为我可以' t真的输入退格...):

这就是我阅读代码的方式。我错过了什么?:

“有一些整数cc等于输入。当输入不等于文件结尾时继续。如果输入是制表符,那么输出\t。如果输入是\然后输出\\。将输入输出到控制台。"

int c;

while((c=getchar())!=EOF)
{
    if(c=='\t')
        {
            putchar('\\');
            putchar('t');
        }

    if(c=='\\')
        {
            putchar('\\');
            putchar('\\');
        }
    putchar(c);
}

【问题讨论】:

  • “如果输入是制表符,则输出 \t。如果输入是 \,则输出 \\。将输入输出到控制台”——如果发生了不止一种情况怎么办?

标签: c getchar putchar


【解决方案1】:

您的主要问题是您正在输出字符,而不管您可能已经输出了它的翻译。那些if 语句将按照您的预期执行,但以它们目前的形式,它们只是直接进入下一个语句。

因此你会寻找类似这样的东西:

while ((c = getchar()) != EOF) {
    // Detect/translate special characters.

    if (c == '\t') {
        putchar ('\\');
        putchar ('t');
        continue;              // Go get next character.
    }

    if (c == '\b') {
        putchar ('\\');
        putchar ('b');
        continue;              // Go get next character.
    }

    if (c == '\\') {
        putchar ('\\');
        putchar ('\\');
        continue;              // Go get next character.
    }

    // Non-special, just echo it.

    putchar (c);
}

另一种更简短、更简洁的可能性是:

while ((c = getchar()) != EOF) {
    // Detect/translate special characters, otherwise output as is.

    switch (c) {
        case '\t': putchar ('\\'); putchar ('t');  break;
        case '\b': putchar ('\\'); putchar ('b');  break;
        case '\\': putchar ('\\'); putchar ('\\'); break;
        default:   putchar (c);
    }
}

【讨论】:

  • 或者你也可以用else if代替if来代替那么多continue
  • 谢谢!你是我的英雄。
  • @theharshest,我更喜欢在开始时使用一组一致的条件而不是缩进地狱的可能性:-) 无论如何,我可能会使用(新)switch 变体来实现它我自己)。
【解决方案2】:

我知道我来晚了,但是这个问题在elsecasecontinue之前的第一章中弹出,并介绍了功能。

这是练习 1-10 的有效解决方案,其中仅涉及到练习点介绍的概念。您需要跟踪是否找到了转义字符,然后仅在未找到时才显示复制的字符。

#include <stdio.h>

int main() {

  int input;

  while((input = getchar()) != EOF){

    int escaped = 0;

    if(input == '\t'){
        putchar('\\');
        putchar('t');
        escaped = 1;
    }

    if(input == '\b'){
        putchar('\\');
        putchar('b');
        escaped = 1;
    }

    if(input == '\\'){
        putchar('\\');
        putchar('\\');
        escaped = 1;
    }

    if(escaped == 0){
      putchar(input);
    }
  }
}

【讨论】:

    【解决方案3】:

    有很多方法可以实现这一点,paxdiablo 提供了一些很好的方法。这是通过functional decomposition 说明DRY principle 的示例:

    void putesc(char c)
    {
        putchar('\\');
        putchar(c);
    }
    
    void ioloop(void)
    {
          for (int c;;)
              switch (c = getchar())
              {
                   case EOF:  return;
                   case '\t': putesc('t'); break;
                   case '\b': putesc('b'); break;
                   case '\\': putesc(c); break;
                   default:   putchar(c); break;
              }
     }
    

    【讨论】:

      【解决方案4】:

      添加另一个解决方案!对于我们这些新手来说,可以很方便地丰富我们,看到各种各样的解决方案。

      #include <stdio.h>
      
      /* a program to copy its input to its output, replacing tab by \t,
          backspace by \b, backslash by \\  */
          
      /* need double backslash to output a single backslash */
      
      int main(){
          
          int c;          /*  to store next character from getchar() */
              
          while((c = getchar()) != EOF){
              if( c != '\t' && c != '\b' && c != '\\')        /* print all characters except special one's */
                  putchar(c);                             
                  
              else{
                  if(c == '\t'){          /* replacing tab by \t */
                      putchar('\\');
                      putchar('t');
                      }
                  
                  if(c == '\b'){          /* replace backspace by \b */ 
                      putchar('\\');
                      putchar('b');
                      }
                      
                  if(c == '\\'){          /* replace backslash by \\ */
                      putchar('\\');
                      putchar('\\');
                      }       
              }
              
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        我是菜鸟。但仅考虑到那时他们所教的内容,我想出了这个答案。

        #include <stdio.h>
        
        main() 
        {
            int c;
        
            c = getchar();
        
            while (c != EOF) {
                if (c == '\t') {
                    putchar('\\');
                    putchar('t');
                }
                else if (c == '\b') {
                    putchar('\\');
                    putchar('b');
                }
                else if (c == '\\') {
                    putchar('\\');
                    putchar('\\');
                }
                else {
                    putchar(c);
                }  
                c = getchar();  
            }
        }
        

        【讨论】:

          【解决方案6】:

          你很亲密。只需将每个块中的第二个“putchar()”更改为赋值语句,即可得到正确的输出。

          int c;
          
          while((c=getchar())!=EOF)
          {
              if(c=='\t')
                  {
                      putchar('\\');
                      c = 't';
                  }
          
              if(c=='\\')
                  {
                      putchar('\\');
                      c = '\\';
                  }
              putchar(c);
          }
          

          【讨论】:

            【解决方案7】:

            就在练习之前,本书提到了 ASCII 代码,而不是更高级的语句。因此,我认为解决方案是面向使用 ASCII 的。

                int c;
                while ( (c = getchar()) != EOF ){
                    //92 is the ASCII code for the backslash \
                    if ( c == '\t'){
                        putchar(92);
                        putchar('t');
                    }else if ( c == '\\' ) {
                        putchar(92);
                        putchar(92);
                    }else if ( c == '\b' ) {
                        putchar(92);
                        putchar('b');
                    }else{
                        putchar(c);
                    }
                }
            

            【讨论】:

            • 书上还说用'A'代替65对程序员阅读代码更好更有用。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-03-25
            相关资源
            最近更新 更多