1. 程式人生 > >編寫一個函式escape(s,t),將字串t複製到字串s中,並在複製過程中將換行符、製表符等不可見字元分別轉換為\n、\t等相應的可見的轉義字元序列。要求使用switch語句。

編寫一個函式escape(s,t),將字串t複製到字串s中,並在複製過程中將換行符、製表符等不可見字元分別轉換為\n、\t等相應的可見的轉義字元序列。要求使用switch語句。

#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
char *unescape(char s[], char t[]);
char *escape(char s[], char t[]);
int main()
{
    char *s = (char*)malloc(sizeof(100));  /*修改處 vc6.0 中 該語句不能放在scanf()語句之後*/
    char t[80];
    scanf("%s", t); 
      printf("%s",t);  

 //char *t = "a\tbelkdjl\td\n";  // 為什麼這樣定義 可以啊?
  //printf("%s\n",t);
 
    printf("%s\n", escape(s, t));  // 呼叫escape()輸出有問題。
    return 0;
}
/*escape : expand newline and tab into visible sequences while copying the string t to s */
char *escape(char s[], char t[])
{
    int i, j;
    for(i = j = 0; t[i] != '\0'; ++i)
        switch(t[i])
        {
        case '\n':      //想輸出\n需要兩個char來儲存,也就是'\\', 'n'
            s[j++] = '\\';
            s[j++] = 'n';
            break;
        case '\t':
            s[j++] = '\\';
            s[j++] = 't';
            break;
        default:
            s[j++] = t[i];
            break;
        }
    s[j] = '\0';
    return s;
}


這裡有個問題 讓我困擾的很久。

1.如果用scanf()函式來輸入字串t,輸入a b(空格代表製表符),輸出a。

後來查了下c plus primer 才知道scanf()在開始讀取輸入以後,會在遇到的第一個空白字元空格(blank)、製表符(tab)或換行符(newline)處停止讀取。因此,在遇到空白字元停止了掃描。一般情況下,使用%s的scanf()只會把一個單詞而不是把整個語句作為字串讀入。這裡空白字元包括製表符、空格、換行符。(書上原話)

但是在用"%c"輸入時,空格和“轉義字元”均作為有效字元。不知道為什麼? 

這裡補充了知識:

scanf遇到以下情況結束讀入
1.white chars 空格,回車,製表符
2.到達%m[d/f/c/s/e/u]指定的寬度m
3.出現非法字元,對於%d來說,非digit就是非法字元,如:'a'


要使字串讀入white chars,C中使用gets,gets是專門處理字串讀入的函式,沒有跳white chars的限制;C++中使用cin.get或者cin.getline

2.能不能scanf()函式接收空白字元?除了gets( )和fgets( )函式。 答案:能

以下是專業回覆。

   問題二:scanf()函式不能正確接受有空格的字串?如: I love you!

#include <stdio.h>
int main()
{
    char str[80];
    
    scanf("%s",str);
    printf("%s",str);
    return 0;
}


輸入:I live you!
輸出:I
       scanf()函式接收輸入資料時,遇以下情況結束一個數據的輸入:(不是結束該scanf函式,scanf函式僅在每一個數據域均有資料,並按回車後結束)。
        ① 遇空格、“回車”、“跳格”鍵。
        ② 遇寬度結束。
        ③ 遇非法輸入。
所以,上述程式並不能達到預期目的,scanf()掃描到"I"後面的空格就認為對str的賦值結束,並忽略後面的"love you!".這裡要注意是"love you!"還在鍵盤緩衝區(關於這個問題,網上我所見的說法都是如此,但是,我經過除錯發現,其實這時緩衝區字串首尾指標已經相等了,也就是說緩衝區清空了,scanf()函式應該只是掃描stdin流,這個殘存資訊是在stdin中)。我們改動一下上面的程式來驗證一下:
#include <stdio.h>
int main()
{
    char str[80];
    char str1[80];
    char str2[80];
    
    scanf("%s",str);/*此處輸入:I love you!  */
    printf("%s",str);
    sleep(5);/*這裡等待5秒,告訴你程式執行到什麼地方*/
    scanf("%s",str1);/*這兩句無需你再輸入,是對鍵盤盤緩衝區再掃描   */
    scanf("%s",str2);/*這兩句無需你再輸入,是對鍵盤盤緩衝區再掃描    */
    printf("\n%s",str1);
    printf("\n%s",str2);
    return 0;
}


輸入:I love you!
輸出:I
      love
      you!
好了,原因知道了,那麼scanf()函式能不能完成這個任務?回答是:能!別忘了scanf()函式還有一個 %[] 格式控制符(如果對%[]不瞭解的請檢視本文的上篇),請看下面的程式:
#include "stdio.h"
int main()
{
    char string[50];
    
     /*scanf("%s",string);不能接收空格符*/
     scanf("%[^\n]",string);  
     printf("%s\n",string);
     return 0;
}


 3. 還有就是 
 //char *t = "a\tbelkdjl\td\n";  // 為什麼這樣定義 可以啊?
  //printf("%s\n",t);

  遇到字串中的字元 '\' 會自動 將後面的字元轉義麼? 即  \t  表示為製表符?