我有这样的字符串 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,这是更新后的字符串的第一个字符。它不会打印字符串中的所有字符。我的代码有什么问题?
答案 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