提问:指针课后习题有关问题

提问:指针课后习题问题。
今天做题,题目如下:输入一个字符串,内有数字和非数字字符,如:A123x456 302tab 5876   将其中连续数字作为一个整数,依次存放到数组a中。例如123放在a【0】,456放在a【1】。。。统计有多少个整数,并输出他们。     

下面是我敲的代码,但是在运行的时候,输入一个字符串之后,程序并没有进行下一步的操作,我自己纠察了半天,没发现错误,特上此寻求各位大哥们的帮助!感激不尽。



# include <stdio.h>

int main(void)
{
char str[50], * pstr;
int i, j, k, m, e10, digit, ndigit, a[10], * pa;

printf("input a string:\n");
gets(str);

pstr = &str[0];
pa = &a[0];
ndigit = 0;
i = 0;
j = 0;

while (*(pstr + i) != '\0')
{
if ((*(pstr + i) >= '0') && (*(pstr + i) <= '9'))//判断是否为数字,并计数
j++;
else
{
if (j > 0) 
{
digit = *(pstr + i - 1) - 48;//遇到非数字字符后,将其前一位置数字赋给digit
k = 1;
while (k < j)
{
e10 = 1;
for (m=1; m<k; m++)    //这里的k和循环的作用是根据之前累计的j的个数,找出十位,百位,千位上的个数分别计算加到digit里
e10 = e10*10;
digit = digit + (*(pstr + i - 1 - k) - 48)*e10;
k++;
}
*pa = digit; //最后的digit赋给数组a的首位,指针pa指向数组下一位,ndigit自增计数,j归0准备下次循环
ndigit++;
pa++;
j = 0;
}
}
}

printf("there are %d numbers in this line, they are:\n", ndigit);

j = 0;
pa = &a[0];

for (j=0 ;j<ndigit; j++)
printf("%d", *(pa + j));
printf("\n");

return 0;
}
------解决思路----------------------
代码挺乱的,贴一段自己的,仅供参考,勿喷
	char str[50] = {0};
int a[25] = {0}; // 50个字符的话,最多不超过25个数字段
printf("input a string:\n");
scanf("%s" ,str);

char *p1 = str; // 遇到数字字符就停住
char *p2 = str; // 遇到非数字字符就结束并转化为数字保存于a中
bool bNumFlag = false; // 是否数字统计状态
int i = 0; // 数组计数器
while (*p1 && *p2)
{
if (*p1 < '0' 
------解决思路----------------------
 *p1 > '9') // p1处于非数字位置
{
p1++;
p2 = p1;
bNumFlag = false;
}
else
{
if (*p2 < '0' 
------解决思路----------------------
 *p2 > '9') // p2处于非数字位置,结束统计,保存进数组
{
int nLen = p2 - p1 + 1;
char *p =(char*) malloc(nLen*sizeof(char));
memset(p ,0 ,nLen);
strncpy_s(p ,nLen,p1,nLen-1);
a[i++] = atoi(p);
free(p);
p2++;
p1 = p2;
bNumFlag = false;
}
else
{
p2++;
bNumFlag  = true;
}
}
}
// 末尾细节处理,如果不处理,结尾的那个数字会遗漏
if (bNumFlag)
{
int nLen = p2-p1+1;
char *p =(char*) malloc(nLen*sizeof(char));
memset(p ,0 ,nLen);
strncpy_s(p ,nLen,p1,nLen-1);
a[i++] = atoi(p);
free(p);
}

------解决思路----------------------
str输入字符串地址 p数组地址 num计数
void func(char *str, int *p, int *num){
//遍历字符串数组
if(str == NULL 
------解决思路----------------------
 p == NULL 
------解决思路----------------------
 num == NULL){
printf("参数有误!");
return;
}
int i = 0;
int j = 0;
char *tempStart = str; //
char *start = str;
int tempPox = 0;  //偏移量
char tempBuff[100];

for(; j <= strlen(str); j++){
//判断是否是数字
if(*tempStart >= '0' && *tempStart <= '9'){
tempPox++;
}else if(tempPox > 0){
memcpy(tempBuff,start,tempPox);
tempBuff[tempPox] = '\0';
p[i] = atoi(tempBuff);
i++;
start += tempPox;
tempPox = 0;
}
if(tempPox == 0){
start++;
}
tempStart++;
}
//整数个数
*num = i;
}

------解决思路----------------------
仅供参考
/*************************************************************************
    > File Name: hello_1.c
    > Author: 傻李
    > Mail: hellojukay@gmail.com 
    > Created Time: 2014年11月21日 星期五 17时39分25秒
 ************************************************************************/

#include<stdio.h>
int main()
{
int state;
int ch;
static int n = 0;
state = 0;//1代表数字,0代表非数字
while((ch = getchar()) != '\n')
{
if(ch >= '0' && ch <= '9')
{
state = 1;
putchar(ch);
}
//如果上一个字符是数字,则输出换行
else if(state == 1)
{
//打印一个换行就有一是一个整数
++n;
//非数字状态
state = 0;
putchar('\n');
}
}
printf("一共有%d个整数\n",n);
return 0;
}

------解决思路----------------------
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.

------解决思路----------------------
引用:
首先感谢您的解答。
流程控制部分光用眼睛看没看懂,,试了几个字母和数字才弄明白,,觉得真是太酷了,,
关于while循环的条件可以理解为*p1 != '\0' && *p2 !='\0'吗
最后一个疑问memset和atoi是啥作用,,不懂,,还没许过这部分知识。
还有就是关于字符串输入的问题。我看书上书的是使用scanf读入字符串的话是不是无法读入带有空格的字符串。如“how do you do”只能输入how。

while循环条件可以理解为该字符不是结束符'\0',因为结束符的ascll值就是0
memset用来初始化一段内存里的值,看下MSDN就明白了,atoi用来将字符串转化为整型int
scanf遇到空格就结束了
------解决思路----------------------
/*
今天做题,题目如下:输入一个字符串,内有数字和非数字字符,如:A123x456 302tab 5876   将其中连续数字作为一个整数,依次存放到数组a中。例如123放在a【0】,456放在a【1】。。。统计
有多少个整数,并输出他们。     

下面是我敲的代码,但是在运行的时候,输入一个字符串之后,程序并没有进行下一步的操作,我自己纠察了半天,没发现错误,特上此寻求各位大哥们的帮助!感激不尽。
*/
#include <stdio.h>

int main(void) {
char str[50], *pstr;
int i, j, digit, ndigit, a[10], *pa;
int indigit = 0;
int start, end;

printf("input a string:\n");
gets(str);

pstr = str;
pa = a;
ndigit = 0;
i = 0;

while (*(pstr + i) != '\0') {
if ((*(pstr + i) >= '0') && (*(pstr + i) <= '9')) {//判断是否为数字,并计数
if(indigit == 0) {
indigit = 1;
start = i;
end = i;
} else {
end++;
}
} else {
if(indigit == 1) {
indigit = 0;
digit = 0;
for(j=start; j<=end; j++) {
digit = digit * 10 + *(pstr + j) - '0';
}
*(pa + ndigit) = digit;
ndigit++;
}
}
i++;
}

printf("there are %d numbers in this line, they are:\n", ndigit);

pa = a;
for (j=0 ;j<ndigit; j++)
printf("%d ", *(pa + j));
printf("\n");

return 0;
}

------解决思路----------------------
引用:
Quote: 引用:

str输入字符串地址 p数组地址 num计数
void func(char *str, int *p, int *num){
//遍历字符串数组
if(str == NULL 
------解决思路----------------------
 p == NULL 
------解决思路----------------------
 num == NULL){
printf("参数有误!");
return;
}
int i = 0;
int j = 0;
char *tempStart = str; //
char *start = str;
int tempPox = 0;  //偏移量
char tempBuff[100];

for(; j <= strlen(str); j++){
//判断是否是数字
if(*tempStart >= '0' && *tempStart <= '9'){
tempPox++;
}else if(tempPox > 0){
memcpy(tempBuff,start,tempPox);
tempBuff[tempPox] = '\0';
p[i] = atoi(tempBuff);
i++;
start += tempPox;
tempPox = 0;
}
if(tempPox == 0){
start++;
}
tempStart++;
}
//整数个数
*num = i;
}


memcpy和atoi这俩是啥作用,,不是很了解,,貌似还没学到。


memcpy 是内存拷贝 atoi是字符转数字
------解决思路----------------------
引用:
Quote: 引用:

首先感谢您的解答。
流程控制部分光用眼睛看没看懂,,试了几个字母和数字才弄明白,,觉得真是太酷了,,
关于while循环的条件可以理解为*p1 != '\0' && *p2 !='\0'吗
最后一个疑问memset和atoi是啥作用,,不懂,,还没许过这部分知识。
还有就是关于字符串输入的问题。我看书上书的是使用scanf读入字符串的话是不是无法读入带有空格的字符串。如“how do you do”只能输入how。

while循环条件可以理解为该字符不是结束符'\0',因为结束符的ascll值就是0
memset用来初始化一段内存里的值,看下MSDN就明白了,atoi用来将字符串转化为整型int
scanf遇到空格就结束了


    我把您的代码复制了一下,在自己的机器上运行,结果系统提示我这样的错误:
 F:\visual 6.0\Cpp3.cpp(26) : error C2065: 'malloc' : undeclared identifier
F:\visual 6.0\Cpp3.cpp(27) : error C2065: 'memset' : undeclared identifier
F:\visual 6.0\Cpp3.cpp(28) : error C2065: 'strncpy_s' : undeclared identifier
F:\visual 6.0\Cpp3.cpp(29) : error C2065: 'atoi' : undeclared identifier
F:\visual 6.0\Cpp3.cpp(30) : error C2065: 'free' : undeclared identifier
Error executing cl.exe.

帮我翻译下上面的话什么意思?
------解决思路----------------------
#include "stdio.h"
void main()
{
    char c[50] = {0};
    int d[25] = {0};
    int i,digit=0,j=0;
    
    scanf("%s",c);
    for(i=0;c[i]!=0;i++)
    {
     if(c[i]>='0'&&c[i]<='9')
     {
     digit = digit*10+(c[i] - '0');
    
     while(c[++i]>='0'&&c[i]<='9')
     {
     digit = digit*10 + (c[i] - '0');
     }
    
     d[j++]=digit;
     digit=0;
     }
    }
    
    for(i=0;i<j;i++)
    printf("%d\n",d[i]);
}

------解决思路----------------------
int main()
{
char desStr[50];
char tempStr[50];
int num[25];
memset(desStr, 0, 50);
memset(tempStr, 0, 50);
memset(num, 0, 25);
bool IsCount = false;
int i = 0;
int index = 0;

cout << "Input a string" << endl;
cin >> desStr;
char *pStr = desStr;
char *pTempStr = pStr;

while (*pStr != '\0')
{
if(!IsCount)
{
if(*pStr >= '0' && *pStr <= '9')
{
i = 0;
tempStr[i] = *pStr;
IsCount = true;
}
}
else
{
if(*pStr < '0' 
------解决思路----------------------
 *pStr > '9')
{
num[index++] = atoi(tempStr);
IsCount = false;
}
else if(*(pStr+1) == '\0' && *pStr >= '0' && *pStr <= '9')
{
tempStr[++i] = *pStr;
num[index++] = atoi(tempStr);
}
else
{
tempStr[++i] = *pStr;
}
}
pStr++;
}

for(int k = 0; (index > 0 ? k < index : k <= 0); ++k)
{
cout << num[k] << endl;
}
return 1;
}