B_booooo 2022-08-17 00:49 采纳率: 53.8%
浏览 43
已结题

请问strtok为什么不能继续输出子串?

华为OD题,简单题

题目2 标题 火星文计算
描述 已知火星人使用的运算符为#、$,其与地球人的等价公式如下:
x#y = 4x+3y+2
x$y = 2*x+y+3
1、其中x,y 是无符号整数
2、地球人公式按C语言规则计算
3、火星人公式中,#的优先级高于$,相同的运算符,按从左到右的顺序计算。
现有一段火星人的字符报文,请你来翻译并计算结果

输入描述
火星人字符串表达式(结尾不带回车换行)
输入的字符串说明:字符串为仅由无符号整数和操作符(#,$)组成的计算表达式。例如:123#4$5#67$78
1、用例保证字符串中,操作数与操作符之间没有任何分隔符
2、用例保证操作数取值范围为32位无符号整数
3、保证输入以及计算结果不会出现整数溢出
4、保证输入的字符串为合法的求值报文,例如123#4$5#67$78
5、保证不会出现非法的求值报文,例如类似这样字符串:
#4$5 //缺少操作数
4$5# //缺少操作数
4#$5 //缺少操作数
4 $5 //有空格
3+4-5*6/7 //有其他操作符
12345678987654321$54321 //32位整数计算溢出

输出描述
根据输入的火星人字符串输出计算结果(结尾不带回车换行)

示例1
输入
7#6$5#12

输出
157

说明
示例:
7#6$5#12
=(47+36+2)$5#12
=48$5#12
=48$(45+312+2)
=48$58
=2*48+58+3
=157

我的问题描述:想用strtok分优先级先按照$分段然后逐段再解决,却发现无法成功输出下一个子串,但我没有用p操作而是复制了内存,不知道为什么无法继续分段?

img

  • 写回答

2条回答 默认 最新

  • 赵4老师 2022-08-17 09:32
    关注

    C:\Program Files (x86)\Microsoft SDK\src\crt\strtok.c

    /***
    *strtok.c - tokenize a string with given delimiters
    *
    *       Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       defines strtok() - breaks string into series of token
    *       via repeated calls.
    *
    *******************************************************************************/
    
    #include <cruntime.h>
    #include <string.h>
    #ifdef _MT
    #include <mtdll.h>
    #endif  /* _MT */
    
    /***
    *char *strtok(string, control) - tokenize string with delimiter in control
    *
    *Purpose:
    *       strtok considers the string to consist of a sequence of zero or more
    *       text tokens separated by spans of one or more control chars. the first
    *       call, with string specified, returns a pointer to the first char of the
    *       first token, and will write a null char into string immediately
    *       following the returned token. subsequent calls with zero for the first
    *       argument (string) will work thru the string until no tokens remain. the
    *       control string may be different from call to call. when no tokens remain
    *       in string a NULL pointer is returned. remember the control chars with a
    *       bit map, one bit per ascii char. the null char is always a control char.
    *
    *Entry:
    *       char *string - string to tokenize, or NULL to get next token
    *       char *control - string of characters to use as delimiters
    *
    *Exit:
    *       returns pointer to first token in string, or if string
    *       was NULL, to next token
    *       returns NULL when no more tokens remain.
    *
    *Uses:
    *
    *Exceptions:
    *
    *******************************************************************************/
    
    char * __cdecl strtok (
            char * string,
            const char * control
            )
    {
            unsigned char *str;
            const unsigned char *ctrl = control;
    
            unsigned char map[32];
            int count;
    
    #ifdef _MT
            _ptiddata ptd = _getptd();
    #else  /* _MT */
            static char *nextoken;
    #endif  /* _MT */
    
            /* Clear control map */
            for (count = 0; count < 32; count++)
                    map[count] = 0;
    
            /* Set bits in delimiter table */
            do {
                    map[*ctrl >> 3] |= (1 << (*ctrl & 7));
            } while (*ctrl++);
    
            /* Initialize str. If string is NULL, set str to the saved
             * pointer (i.e., continue breaking tokens out of the string
             * from the last strtok call) */
            if (string)
                    str = string;
            else
    #ifdef _MT
                    str = ptd->_token;
    #else  /* _MT */
                    str = nextoken;
    #endif  /* _MT */
    
            /* Find beginning of token (skip over leading delimiters). Note that
             * there is no token iff this loop sets str to point to the terminal
             * null (*str == '\0') */
            while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
                    str++;
    
            string = str;
    
            /* Find the end of the token. If it is not the end of the string,
             * put a null there. */
            for ( ; *str ; str++ )
                    if ( map[*str >> 3] & (1 << (*str & 7)) ) {
                            *str++ = '\0';
                            break;
                    }
    
            /* Update nextoken (or the corresponding field in the per-thread data
             * structure */
    #ifdef _MT
            ptd->_token = str;
    #else  /* _MT */
            nextoken = str;
    #endif  /* _MT */
    
            /* Determine if a token has been found. */
            if ( string == str )
                    return NULL;
            else
                    return string;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月26日
  • 已采纳回答 8月18日
  • 创建了问题 8月17日

悬赏问题

  • ¥15 r语言神经网络自变量重要性分析
  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢