Thomas
Thomas

Reputation: 117

K&R c programming book 2nd version, exercise 3-2, a subtle error I wrote

When I write the exercise 3-2, which is escape characters and unescape characters:I run into a subtle problem, I cannot figure it out:

#include <stdio.h>
void escape(char s[], char t[]);
void unescape(char s[], char t[]);
int main(){
   char s[] = "we can run all the \n \t \n \t \t programs on it";
   char t[100];
   char m[100];
   int n = 0;
   escape(s, t);
   printf("%s\n", s);
   printf("%s\n", t);
   unescape(t, m);
   printf("%s\n", m);
}
void escape(char s[], char t[]){
   int i, j;
   for (i = j = 0; s[i] != '\0' ; i++){
   switch(s[i]){
      case '\n':
         t[j++] = '\\';
         t[j++] = 'n';
         break;
      case '\t':
         t[j++] = '\\';
         t[j++] = 't';
         break;
      default:
         t[j++] = s[i];
         break;
   }
   }
   t[j] = '\0';
}
void unescape(char t[], char m[]){
   int i, j;
   for (i = j = 0; t[i] != '\0'; i++){
      switch(t[i]){
         case '\\':
             switch(t[++i]){
                case 'n':
                  m[j++] = '\n';
                  break;
                case 't':
                  m[j++] = '\t';
                  break;
                default:
                  break;
             }
         default:
            m[j++] = t[i];
            break;
      }
   }
   m[j] = '\0';
}

well, I leave out all the comments, hope it is simple enough to understand compile it and run it, I got the following result:

enter image description here

how come at the end when I unescape to the real characters I get the redundant n,n,t,t, at the same time, tab and newline are working as expected?

Upvotes: 2

Views: 88

Answers (1)

4386427
4386427

Reputation: 44256

The unescape function has no break statement in case '\\': so it will fall through to the default.

I assume that is why you get what you call "the redundant n,n,t,t"

Change it to:

  switch(t[i]){
     case '\\':
         switch(t[++i]){
            case 'n':
              m[j++] = '\n';
              break;
            case 't':
              m[j++] = '\t';
              break;
            default:
              break;
         }
         break;  // add this

and you'll get another output.

BTW: With proper compiler flags, your compiler would have warned you about this.

Rule number 1: Never ignore warnings...

Upvotes: 5

Related Questions