char数组中的增量数字由不同的分隔符分隔

时间:2014-12-26 18:10:28

标签: c++ c

我有这样的字符串 1-2,4 ^,14-56
我期待输出 2-3,5 ^,15-57

char input[48];
int temp;
char *pch;

pch = strtok(input, "-,^");

while(pch != NULL)
{
    char tempch[10];
    temp = atoi(pch);
    temp++;
    itoa(temp, tempch, 10);
    memcpy(pch, tempch, strlen(tempch));
    pch = strtok(NULL, "-,^");
}

完成此操作后,如果我打印输入,它只打印2,这是更新后的字符串的第一个字符。它不会打印字符串中的所有字符。我的代码有什么问题?

4 个答案:

答案 0 :(得分:2)

此代码存在两个主要问题: 首先,

pch = strtok(input, ",");

当应用于字符串1-2,4^,14-56时,将返回令牌1-2

当您致电atoi("1-2")时,您将获得1,并转换为2

您可以通过将第一个strtok更改为pch = strtok(NULL, "-,^");

来解决此问题

其次,strtok修改了字符串,这意味着你丢失了找到的原始分隔符。由于这看起来像是一项家庭作业,我会告诉你如何解决这个问题。

答案 1 :(得分:2)

对于普通C,请使用库函数strtod。除了atoi之外,这可以更新指向下一个未解析字符的指针:

  

long strtol (const char * restrict str ,char ** restrict endptr ,int base );
  ...
   strtol()函数将 str 中的字符串转换为long值。 [...]如果 endptr 不为NULL, strtol()会在 * endptr 中存储第一个无效字符的地址。

由于数字之间可能有多个“非数字”字符,因此请使用库函数isdigit跳过它们。我把它放在循环的开头,这样就不会意外地将-2,3之类的字符串转换为-1,4 - 首先会拾取初始-2! (如果在其他地方这是一个问题,那么还有一个strtoul。)

由于您希望结果存在于 char 字符串中,因此我使用sprintf将输出复制到缓冲区中,该缓冲区必须足够大才能输入 plus 由十进制溢出引起的额外字符。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

int main (void)
{
    char *inputString = "1-2,4^,14-56";
    char *next_code_at = inputString;
    long result;
    char dest[100], *dest_ptr;

    printf ("%s\n", inputString);

    dest[0] = 0;
    dest_ptr = dest;
    while (next_code_at && *next_code_at)
    {
        while (*next_code_at && !(isdigit(*next_code_at)))
        {
            dest_ptr += sprintf (dest_ptr, "%c", *next_code_at);
            next_code_at++;
        }
        if (*next_code_at)
        {
            result = strtol (next_code_at, &next_code_at, 10);
            if (errno)
            {
                perror ("strtol failed");
                return EXIT_FAILURE;
            } else
            {
                if (result < LONG_MAX)
                    dest_ptr += sprintf (dest_ptr, "%ld", result+1);
                else
                {
                    fprintf (stderr, "number too large!\n");
                    return EXIT_FAILURE;
                }
            }
        }
    }
    printf ("%s\n", dest);

    return EXIT_SUCCESS;
}

示例运行:

Input:  1-2,4^,14-56
Output: 2-3,5^,15-57

答案 2 :(得分:1)

strtok修改传递给它的字符串。使用strchr或类似的东西来查找分隔符或制作要处理的字符串的副本。

答案 3 :(得分:1)

我认为这可以更容易地使用正则表达式(当然还有C ++而不是C语言):

完整的例子:

#include <iostream>
#include <iterator>
#include <regex>
#include <string>

int main()
{

    // Your test string.
    std::string input("1-2,4^,14-56");
    // Regex representing a number.
    std::regex number("\\d+");

    // Iterators for traversing the test string using the number regex.
    auto ri_begin = std::sregex_iterator(input.begin(), input.end(), number);
    auto ri_end = std::sregex_iterator();


    for (auto i = ri_begin; i != ri_end; ++i)
    {
        std::smatch match = *i;                             // Match a number.
        int value = std::stoi(match.str());                 // Convert that number to integer.
        std::string replacement = std::to_string(++value);  // Increment 1 and convert to string again.

        input.replace(match.position(), match.length(), replacement); // Finally replace.
    }

    std::cout << input << std::endl;

    return 0;
}

输出:

2-3,5^,15-57