灵异事件,求真相。。。

kog2333 2016-05-13 12:47:45
自学C Primer中,看书做题刚到第7章,然后练习题里有这样一个题目

要求输出一个句子,遇到'#'结束,然后把句子中的'.'(句号)替换为'!'(感叹号),把'!'(感叹号)替换为'!!'(感叹号X2),然后输出替换后的句子


#include<stdio.h>
#include<string.h>
const char Stop = '#';
const char Symbol_1 = '.';
const char Symbol_2 = '!';
const int MaxLen = 100;
int main(void)
{
char chs[MaxLen];
char Letter;
int Counts = 0;
int Times = 0;
printf("Please Input Words To Test:\n");
while((Letter = getchar()) != Stop)
{
if(Letter == Symbol_1)
{
chs[Counts] = Symbol_2;
++Counts;
++Times;
}
else
if(Letter == Symbol_2)
{
chs[Counts] = Symbol_2;
chs[Counts+1] = Symbol_2;
Counts += 2;
++Times;
}
else
{
chs[Counts] = Letter;
++Counts;
}
}
printf("%d Times\n",Times);
printf("%s\n",chs); //<----这个很奇葩
// int Len = strlen(chs); //<---问题出在这3行代码里
// for(int i = 0 ; i < Len+1 ; ++i)
// printf("%c ",chs[i]);
return 0;
}

本来我写好代码(开始没加那3行代码),编译运行后出现一个问题,比如我输入'qwqw..!!#qw'
然后替换次数为4次,这没问题,但最后用printf()显示替换后的字符串,正确的结果应该是qwqw!!!!!!
但在我的系统(ubuntukylin14.04)里结果是
qwqw!!!!!!D 
字符串后面莫名其妙的多了2个不知道是什么东东。。。
然后我为了确认下这2个奇葩到底是什么,所以就在代码上加了那3行,我本来想着一个一个的输出,看看最后2个字符到底是什么,

结果。。。。编译完成后运行程序,我发现程序好了。。。
这时候我在输入'qwqw..!!#qw'
结果为
qwqw!!!!!!! <----最关键的是我想知道为什么这行也正常了。。。。
q w q w ! ! ! ! ! ! !
...全文
195 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-05-13
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
paschen 2016-05-13
  • 打赏
  • 举报
回复
字符串以\0结尾,如果找不到\0,就会一直去解析这个字符串,导致出现一些乱码
LubinLew 2016-05-13
  • 打赏
  • 举报
回复
数组没有初始化,导致printf和strlen结果错误

#include<stdio.h>
#include<string.h>

const char Stop = '#';
const char Symbol_1 = '.';
const char Symbol_2 = '!';
const int MaxLen = 100;

int main(void)
{
  char chs[MaxLen] = {0};///////////  need init, otherwise printf chs will not work correct
  int Letter; ///////////////////////// getchar return int not char
  int Counts = 0;
  int Times = 0;
  
  printf("Please Input Words To Test:\n");
  while ((Letter = getchar()) != Stop)
  {
    if (Letter == Symbol_1)
    {
      chs[Counts] = Symbol_2;
      ++Counts;
      ++Times;
    }
    else if(Letter == Symbol_2)
    {
        chs[Counts++] = Symbol_2;
        chs[Counts++] = Symbol_2;
        ++Times;
     }
     else if ((Letter == EOF) || (Letter == '\n')) //////////////////////in case the wrong input
     {//parse input done
     	break;
     }
	 else
     {
        chs[Counts] = Letter;
        ++Counts;
     }
  }
  printf("%d Times\n",Times);
  printf("%s\n",chs);   //<----Õâ¸öºÜÆæÝâ ---------------------->see line 10
  int Len = strlen(chs);    //<---ÎÊÌâ³öÔÚÕâ3ÐдúÂëÀï
  for(int i = 0 ; i < Len+1 ; ++i)
    printf("%c ",chs[i]);
 return 0;
}
kog2333 2016-05-13
  • 打赏
  • 举报
回复
引用 3 楼 brookmill 的回复:
这里面有两个重点: 1. c语言的字符串是要依靠结束符'\0'来判断字符串的结尾 2. 局部变量如果不明确的初始化,它可能是任何值。可能是0,也可能不是0。1楼的memset就是一种初始化。 另一个问题:Counts不断增加的过程中每次都要判断是否超过了MaxLen,否则数组越界了很麻烦的。
其实我好奇的不是这个。。 我最好奇的是为什么我下面加了那3行(就是注释掉的),为什么上面的那句printf()会受到影响。。。
  • 打赏
  • 举报
回复
在printf输出前面加上这个,chs[Counts] = '\0';
brookmill 2016-05-13
  • 打赏
  • 举报
回复
这里面有两个重点: 1. c语言的字符串是要依靠结束符'\0'来判断字符串的结尾 2. 局部变量如果不明确的初始化,它可能是任何值。可能是0,也可能不是0。1楼的memset就是一种初始化。 另一个问题:Counts不断增加的过程中每次都要判断是否超过了MaxLen,否则数组越界了很麻烦的。
brookmill 2016-05-13
  • 打赏
  • 举报
回复
大概是因为字符串结束符。 两个办法: 1. 在while之前memset(chs, 0, sizeof(chs)); 2. 在while之后chs[Counts] = '\0';
kog2333 2016-05-13
  • 打赏
  • 举报
回复
我擦。。输出最后没的2个火星字符csdn都显示不出来。。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧