编写一个函数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  表示为制表符? 
 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值