如何从字符串中提取整数?
How can I extract an integer from within a string?
我正在做一项作业,作为作业的一部分,我需要从字符串中提取整数。
我试过使用atoi()
函数,但它总是returns一个0
,所以我切换到strtol()
,但它仍然returns一个0
.
目标是从字符串中提取整数并将它们作为参数传递给不同的函数。我正在使用一个函数,然后使用这些值来更新一些数据 (update_stats
)。
请记住,我对 C 语言编程还很陌生,但这是我的尝试:
void get_number (char str[]) {
char *end;
int num;
num = strtol(str, &end, 10);
update_stats(num);
num = strtol(end, &end, 10);
update_stats(num);
}
这样做的目的是在字符串 "e5 d8"
中(例如)我将从该字符串中提取 5
和 8
。
字符串的格式始终相同。
我该怎么做?
strtol
不会 找到 字符串中的数字。它转换字符串开头的数字。 (它确实跳过空格,但没有别的。)
如果您需要查找数字的起始位置,可以使用类似以下内容的方法:
const char* nump = strpbrk(str, "0123456789");
if (nump == NULL) /* No number, handle error*/
如果您的号码可能已签名,则需要一些更复杂的东西。一种方法是执行上述操作,然后如果前一个字符是 -
,则备份一个字符。但要注意字符串的开头:
if ( nump != str && nump[-1] == '-') --nump;
只需将 -
放入 strpbrk
参数中就会在输入上产生错误匹配,例如 non-numeric7
.
如果格式总是这样,那么这个也可以
#include <stdio.h>
int main()
{
char *str[] = {"a5 d8", "fe55 eec2", "a5 abc111"};
int num1, num2;
for (int i = 0; i < 3; i++) {
sscanf(str[i], "%*[^0-9]%d%*[^0-9]%d", &num1, &num2);
printf("num1: %d, num2: %d\n", num1, num2);
}
return 0;
}
输出
num1: 5, num2: 8
num1: 55, num2: 2
num1: 5, num2: 111
%[^0-9]
将匹配任何非数字字符。通过像这样添加 *
%*[^0-9]
表示要从字符串中读取数据,但忽略。
我建议你自己写逻辑。我知道,这就像 重新发明轮子 ,但在那种情况下,您将深入了解库功能的实际工作方式。
这是我建议的功能:
bool getNumber(str,num_ptr)
char* str;
long* num_ptr;
{
bool flag = false;
int i = 0;
*num_ptr = 0;
char ch = ' ';
while (ch != '[=10=]') {
ch = *(str + i);
if (ch >= '0' && ch <= '9') {
*num_ptr = (*num_ptr) * 10 + (long)(ch - 48);
flag = true;
}
i++;
}
return flag;
}
不要忘记传递一个末尾带有 [=11=]
的字符串 :)
我正在做一项作业,作为作业的一部分,我需要从字符串中提取整数。
我试过使用atoi()
函数,但它总是returns一个0
,所以我切换到strtol()
,但它仍然returns一个0
.
目标是从字符串中提取整数并将它们作为参数传递给不同的函数。我正在使用一个函数,然后使用这些值来更新一些数据 (update_stats
)。
请记住,我对 C 语言编程还很陌生,但这是我的尝试:
void get_number (char str[]) {
char *end;
int num;
num = strtol(str, &end, 10);
update_stats(num);
num = strtol(end, &end, 10);
update_stats(num);
}
这样做的目的是在字符串 "e5 d8"
中(例如)我将从该字符串中提取 5
和 8
。
字符串的格式始终相同。
我该怎么做?
strtol
不会 找到 字符串中的数字。它转换字符串开头的数字。 (它确实跳过空格,但没有别的。)
如果您需要查找数字的起始位置,可以使用类似以下内容的方法:
const char* nump = strpbrk(str, "0123456789");
if (nump == NULL) /* No number, handle error*/
如果您的号码可能已签名,则需要一些更复杂的东西。一种方法是执行上述操作,然后如果前一个字符是 -
,则备份一个字符。但要注意字符串的开头:
if ( nump != str && nump[-1] == '-') --nump;
只需将 -
放入 strpbrk
参数中就会在输入上产生错误匹配,例如 non-numeric7
.
如果格式总是这样,那么这个也可以
#include <stdio.h>
int main()
{
char *str[] = {"a5 d8", "fe55 eec2", "a5 abc111"};
int num1, num2;
for (int i = 0; i < 3; i++) {
sscanf(str[i], "%*[^0-9]%d%*[^0-9]%d", &num1, &num2);
printf("num1: %d, num2: %d\n", num1, num2);
}
return 0;
}
输出
num1: 5, num2: 8
num1: 55, num2: 2
num1: 5, num2: 111
%[^0-9]
将匹配任何非数字字符。通过像这样添加 *
%*[^0-9]
表示要从字符串中读取数据,但忽略。
我建议你自己写逻辑。我知道,这就像 重新发明轮子 ,但在那种情况下,您将深入了解库功能的实际工作方式。
这是我建议的功能:
bool getNumber(str,num_ptr)
char* str;
long* num_ptr;
{
bool flag = false;
int i = 0;
*num_ptr = 0;
char ch = ' ';
while (ch != '[=10=]') {
ch = *(str + i);
if (ch >= '0' && ch <= '9') {
*num_ptr = (*num_ptr) * 10 + (long)(ch - 48);
flag = true;
}
i++;
}
return flag;
}
不要忘记传递一个末尾带有 [=11=]
的字符串 :)