一道C语言题,复查了很长时间能通过编译,但就是不能实现想要的功能

Marvel_Z 2014-01-25 09:26:11
程序的功能是从一段字符串中提取出连着的的6位数字,数字必须连续
以下是程序
#include <stdio.h>
#define NUM 6
void main()
{
int pw[NUM],str[100];
int *p;
int i,count0=0,j=0;//count0为数字计数器
scanf("%s",str);
p=str;
for(i=0;*(p+i)!='\0';i++)
{
if(count0==NUM)
if((*(p+i))>='0'&&(*(p+i)<='9'))
{
count0=0;
j=0;
}//check
else
break;
if((*(p+i)>='0')&&(*(p+i)<='9'))
{
count0++;
pw[j]=*(p+i);
j++;
}
else
{
count0=0;
j=0;
}
}
if(count0==NUM)
printf("The password is:%s\n",pw);
else
printf("ERROR!\n");
}
...全文
174 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Marvel_Z 2014-01-26
  • 打赏
  • 举报
回复
引用 7 楼 ALNG 的回复:
如果你的意思确实是连续6位但不能多于6位数字的话,我确实又想到了一个问题。你先自己想想。 如果输入的是 1234567223456abcdef789432 你期待你的程序给出什么结果?我估计是789432, 但你的程序实际会给出什么答案呢?223456 你的水平搞定这个问题绰绰有余,留给你自己吧。
感谢大家的热情回复!经历过这个小程序,越发的觉得自己的思维不够严密了。 作为一个新手,我觉得还是练习量不够,看来还得多多练习才行。 话说现在我觉得对于一个程序员来说最可怕的不是不会如何编出程序实现自己想要的功能,而是想不到会出现的所有情况。
木木口口 2014-01-26
  • 打赏
  • 举报
回复
1. p定义应该是char *类型的,int *类型的指针一般++滞后跳过四个字节,char *类型的是一个字节 2. 使用%s输出pw,pw最后最好加上\0,要不然也可能引起异常 3. 字符'0'和数字0对应的值是不一样的
赵4老师 2014-01-26
  • 打赏
  • 举报
回复
参考《编译原理》中的词法分析和有限状态自动机。
孩皮妞野 2014-01-25
  • 打赏
  • 举报
回复
如果你的意思确实是连续6位但不能多于6位数字的话,我确实又想到了一个问题。你先自己想想。 如果输入的是 1234567223456abcdef789432 你期待你的程序给出什么结果?我估计是789432, 但你的程序实际会给出什么答案呢?223456 你的水平搞定这个问题绰绰有余,留给你自己吧。
孩皮妞野 2014-01-25
  • 打赏
  • 举报
回复
神啊,还以为是6位连续的数字,还说这密码有够弱的 :)

char * get_password(char * str)
{
     char *p=NULL, ch;
     while((ch=*str)!=0)
     {
         if(ch<'0' || ch>'9')
         {
             p=NULL;
             continue;
         }
         if(str-p==5) //到了
         {
              *++str='\0'; // 加入字符串结束标志
              return p;
         }
     }
     return NULL;
}
检查一下你的代码

#include <stdio.h>
#define NUM 6
void main()
{
    int pw[NUM],str[100];
    int *p;
    int i,count0=0,j=0;//count0为数字计数器
    scanf("%s",str);
    p=str;
    for(i=0;*(p+i)!='\0';i++)
    {
        if(count0==NUM)// 检查count0==NUM应该放在读到一个数字为并把count0计数器自加之后
            if((*(p+i))>='0'&&(*(p+i)<='9'))  // 这里的意思是不是要连续6位,不能多也不能少?
                {
                    count0=0;   //注意 *(p+i)等价于p[i], 后一种写法显得简洁些。
                    j=0;
            }//check
            else
                break;
        if((*(p+i)>='0')&&(*(p+i)<='9'))
            {
                count0++;
                pw[j]=*(p+i);
                j++;
        }
        else
            {
                count0=0;
                j=0;
        }
    }
    if(count0==NUM)
        printf("The password is:%s\n",pw); // 上面的提到过了,如果你准备这样操作pw串
    else                                   // 有必要在其后加一个"\0"结束标志,先把
        printf("ERROR!\n");                // 其定义为 char pw[NUM+1];
}
对了,楼上的mend已经给出的正确答案,问题出在str应该定义成char数组。 逻辑上还真没读出什么问题,如果你的意思确实是连续6位但不能多余6为的数字的话。 还有个你的p变量初始化后完全没有再对它赋过值,可以省略他,直接用str就行的,而且所有*(p+i)的表达都可以对应替换为str[i],当然这些并不影响程序的行为,甚至也不影响效率。 修改后的程序

#include <stdio.h>
#define NUM 6
void main()
{
    char pw[NUM+1],str[100];
 
    int i,count0=0,j=0;//count0为数字计数器
    scanf("%s",str);
    
    pw[6]='\0';
    
    for(i=0;str[i]!='\0';i++)
    {
        if(count0==NUM)
            if((str[i])>='0'&&(str[i]<='9'))
                {
                    count0=0;
                    j=0;
            }//check
            else
                break;
        if((str[i]>='0')&&(str[i]<='9'))
        {
                pw[j++]=str[i];
                if(++count0==6)
                {
                    
                };
        }
        else
            {
                count0=0;
                j=0;
        }
    }
    if(count0==NUM)
        printf("The password is:%s\n",pw);
    else
        printf("ERROR!\n");
}
孩皮妞野 2014-01-25
  • 打赏
  • 举报
回复
逻辑有问题吧? 办法1: 记住前一个数字位的值(非数字位的话用-1), 记住当前读到的连续数字位的个数,到6就OK了。

void get_password(const char * str, char password[])
{
     int count=0;
     int v=-1, c;
     password[0]='\0'; // 以防输入串中不存在密码
     while((c=*str)!=0)
     {
         if(c>='0' && c<='9')
         {
             if(++v==c) //检查是否连续
             {
                  if(++count==6) //检查是否也读到了足够的连续位
                  {
                       // 如果是,保留并退出
                       for(int i=5; i>=0; --i, --c)
                         password[i]=c;
                       return;
                  }
             }else //不连续,就从1开始
             {
                  v=c;
                  count=1;
             }
         }else{
             v=-1;
             count=0; // 这句也可以comment掉
         }
     }
     
}
如果考虑到第一个数位不能大于'9'-5, 还可以利用这个只是进一步改进上面的程序,这是小修小补,完成功能后再锦上添花。 办法2,记住这一次连续数字开始的位置,如果输入串可以改写,这个办法会更快一些

char * get_password(char * str)
{
     char *p=NULL, ch;
     while((ch=*str)!=0)
     {
         if(ch<'0' || ch>'9')
         {
             p=NULL;
             continue;
         }
         if(!p || ch-*p!=str-p){ // 利用ch-*p与str-p是否相等来判断是否连续
             p=str;
             continue;
         }
         // 如果走到这里,前面是连续的,判断是否已经到了6个
         if(str-p==5) //到了
         {
              *++str='\0'; // 加入字符串结束标志
              return p;
         }
     }
     return NULL;
}
kids_hiank 2014-01-25
  • 打赏
  • 举报
回复
代码逻辑上过得去, 不过严格来讲, 是有不合理处的....str 数组用来保存的是 字串, 应该用 char型的; pw用于打印的话, 应该给个结束符;
mujiok2003 2014-01-25
  • 打赏
  • 举报
回复
#include <stdio.h>
#define NUM 6
int main()
{
  char str[100],*p;
  int i,j;//count0为数字计数器
  scanf("%99s",str);
  for(i = 0 ; str[i] ;i++)
  {
    for(p = str + i, j = 0; j < 6 &&  p[j]; ++j)    
    {
      if(p[j] < '0' ||  p[j] >'9')
      {
        break;
      }
    }
    if(j == NUM)
    {
      break;
    }
  }
  if(j==NUM)
    printf("The password is:%.6s\n",p);
  else
    printf("ERROR!\n");
  return 0;
}
mujiok2003 2014-01-25
  • 打赏
  • 举报
回复
http://ideone.com/6C6dGC
kids_hiank 2014-01-25
  • 打赏
  • 举报
回复
int *p 改为 char *p

70,020

社区成员

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

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