如何从字符串中提取多位数字?
How to extract multi-digit numbers from a string?
首先,我知道以前有人问过类似的问题,但我相信我的情况有所不同。
我的输入字符串是:
(5,7) (1,6) (2,4) (10,14) (8,9)
我写了下面的提取数组的代码。
main(){
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x){
if((s[i]=='(' && s[i+2]==',') || (s[i]==',' && s[i+2]==')'))
{
a[n]=s[i+1]-'0';
n++;
}
i++;
}
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
}
我得到的输出是:
5 7 1 6 2 4 8 9
我明白为什么我的代码会跳过具有 2 位或更多位数字的数字。
请建议对当前代码进行一些小改动以修复此限制。
P.S.- 我正在寻找一个不依赖于数字长度的解决方案。
我使用了不同的方法来解决这个问题,但我已经解决了它并且它有效。考虑试试这个。顺便说一句,我使用 char *s 作为字符串文字,但您可以像您一样保留它。
main(){
char *s="(5,7) (1,6) (2,4) (10,14) (8,9)";
int i=0,x,n=0;
char a[20];
x=strlen(s);
while(i<x){
if (isdigit(s[i])) {
a[n]=s[i];
if (s[i+1]==',' || s[i+1]==')') {
a[n+1]=' ';
n++;
}
n++;
}
i++;
}
printf("%s\n", a);
}
输出:
tenshi@mashiro:~/projects/test$ ./test
5 7 1 6 2 4 10 14 8 9
#include <stdio.h>
int main(void) {
// your code goes here
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x-1){
if(isdigit(s[i]))
{
if(isdigit(s[i+1]))
{
a[n]=(s[i]-'0')*10 +(s[i+1]-'0');
i++;
}
else
{
a[n]=s[i]-'0';
}
n++;
}
i++;
}
printf("\n");
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
return 0;
}
上面的代码呢,不幸的是C没有简单的字符串函数,比如split with Regex(它有split函数,但我不太明白)。或者,这里是 ideone for it https://ideone.com/eRKTbD
如果输入的格式与问题中的格式完全相同,那么您可以在主 while 循环中添加两个循环以一次读取一组。
while (i < x)
{
if (s[i] == '(')
{
// temporary var to store number
int num = 0;
// read first number
while (s[++i] != ',')
num = num*10 + s[i]-'0';
a[n++] = num;
num = 0;
// read second number
while (s[++i] != ')')
num = num*10 + s[i]-'0';
a[n++] = num;
}
i++;
}
由于您只关心数字而不关心任何分隔符,因此您可以使用 strtok
,它允许使用一组分隔符。
使用以下代码代替现有的 while
循环:
char *p = strtok(s, "(), ");
while (p) {
a[n++] = atoi(p);
p = strtok(NULL, "(), ");
}
输出:
5
7
1
6
2
4
10
14
8
9
如果你对格式比较讲究,可以这样做:
char *start = s, *p1 = NULL, *p2 = NULL, *p3 = NULL;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
while (p1 && p2 && p3) {
a[n++] = atoi(p1+1);
a[n++] = atoi(p2+1);
start = p3+1;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
}
如果您始终使用相同的格式 (a,b)(c,d)...(y,z) 和相同数量的值,那么此解决方案有效:
char * arr = "(5,7)(1,6)(2,4)(10,14)(8,9)";
int a,b,c,d,e,f,g,h,i,j;
sscanf(arr,"(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)",&a,&b,&c,&d,&e,&f,&g,&h,&i,&j);
printf("%d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, j);
首先,我知道以前有人问过类似的问题,但我相信我的情况有所不同。
我的输入字符串是:
(5,7) (1,6) (2,4) (10,14) (8,9)
我写了下面的提取数组的代码。
main(){
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x){
if((s[i]=='(' && s[i+2]==',') || (s[i]==',' && s[i+2]==')'))
{
a[n]=s[i+1]-'0';
n++;
}
i++;
}
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
}
我得到的输出是:
5 7 1 6 2 4 8 9
我明白为什么我的代码会跳过具有 2 位或更多位数字的数字。 请建议对当前代码进行一些小改动以修复此限制。
P.S.- 我正在寻找一个不依赖于数字长度的解决方案。
我使用了不同的方法来解决这个问题,但我已经解决了它并且它有效。考虑试试这个。顺便说一句,我使用 char *s 作为字符串文字,但您可以像您一样保留它。
main(){
char *s="(5,7) (1,6) (2,4) (10,14) (8,9)";
int i=0,x,n=0;
char a[20];
x=strlen(s);
while(i<x){
if (isdigit(s[i])) {
a[n]=s[i];
if (s[i+1]==',' || s[i+1]==')') {
a[n+1]=' ';
n++;
}
n++;
}
i++;
}
printf("%s\n", a);
}
输出:
tenshi@mashiro:~/projects/test$ ./test
5 7 1 6 2 4 10 14 8 9
#include <stdio.h>
int main(void) {
// your code goes here
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x-1){
if(isdigit(s[i]))
{
if(isdigit(s[i+1]))
{
a[n]=(s[i]-'0')*10 +(s[i+1]-'0');
i++;
}
else
{
a[n]=s[i]-'0';
}
n++;
}
i++;
}
printf("\n");
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
return 0;
}
上面的代码呢,不幸的是C没有简单的字符串函数,比如split with Regex(它有split函数,但我不太明白)。或者,这里是 ideone for it https://ideone.com/eRKTbD
如果输入的格式与问题中的格式完全相同,那么您可以在主 while 循环中添加两个循环以一次读取一组。
while (i < x)
{
if (s[i] == '(')
{
// temporary var to store number
int num = 0;
// read first number
while (s[++i] != ',')
num = num*10 + s[i]-'0';
a[n++] = num;
num = 0;
// read second number
while (s[++i] != ')')
num = num*10 + s[i]-'0';
a[n++] = num;
}
i++;
}
由于您只关心数字而不关心任何分隔符,因此您可以使用 strtok
,它允许使用一组分隔符。
使用以下代码代替现有的 while
循环:
char *p = strtok(s, "(), ");
while (p) {
a[n++] = atoi(p);
p = strtok(NULL, "(), ");
}
输出:
5
7
1
6
2
4
10
14
8
9
如果你对格式比较讲究,可以这样做:
char *start = s, *p1 = NULL, *p2 = NULL, *p3 = NULL;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
while (p1 && p2 && p3) {
a[n++] = atoi(p1+1);
a[n++] = atoi(p2+1);
start = p3+1;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
}
如果您始终使用相同的格式 (a,b)(c,d)...(y,z) 和相同数量的值,那么此解决方案有效:
char * arr = "(5,7)(1,6)(2,4)(10,14)(8,9)";
int a,b,c,d,e,f,g,h,i,j;
sscanf(arr,"(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)",&a,&b,&c,&d,&e,&f,&g,&h,&i,&j);
printf("%d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, j);