簡體   English   中英

char數組中由不同分隔符分隔的遞增數字

[英]Increment numbers in char array separated by different delimiters

我有這樣的字符串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,這是更新字符串的第一個字符。 它不會打印字符串中的所有字符。 我的代碼有什么問題?

此代碼有兩個主要問題:首先,

pch = strtok(input, ",");

當應用於字符串1-2,4^,14-56將返回令牌1-2

當您調用atoi("1-2")您將獲得1 ,它將轉換為2

您可以通過將第一個strtok更改為pch = strtok(NULL, "-,^");來解決此問題pch = strtok(NULL, "-,^");

其次,strtok修改字符串,這意味着您丟失了找到的原始定界符。 因為這看起來像是一項家庭作業,所以我將讓您了解如何解決此問題。

對於純C語言,請使用庫函數strtod 除了atoi ,這可以將指針更新為下一個未解析的字符:

strtol (const char * restrict str ,char ** restrict endptr ,int base );
...
strtol()函數將str中的字符串轉換為長值。 [...]如果endptr不為NULL,則strtol()將第一個無效字符的地址存儲在* endptr中

由於數字之間可能有多個“非數字”字符,請使用庫函數isdigit跳過它們。 我將其放置在循環的開頭,這樣它就不會意外地將諸如-2,3的字符串轉換為-1,4 -最初的-2將首先被拾取! (如果這在其他地方是一個問題,那么也有一個strtoul 。)

由於似乎需要將結果保存在char字符串中,因此我使用sprintf將輸出復制到緩沖區中,該緩沖區必須足夠大以容納可能的輸入以及由十進制溢出引起的額外字符。

#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

strtok修改傳遞給它的字符串。 使用strchr或類似的東西來查找定界符或復制要處理的字符串。

我認為可以通過使用正則表達式(和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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM