简体   繁体   中英

How can I extract only numbers from a string?

I want to extract only numbers from a string, and to put them in an array.

For example, string is "fds34 21k34 k25j 6 10j340ii0i5" .

I want to make one array, which elements are like following:

arr[0]=34, arr[1]=21, arr[2]=34, arr[3]=25, arr[4]=6, arr[5]=10, arr[6]=340, arr[7]=0, arr[8]=5;

my trial code:

#include <stdio.h>
int main()
{
    char ch;
    int i, j;
    int pr[100];
    i=0;
    while ( (ch = getchar()) != '\n' ){
        if( ch>='0' && ch<='9' ){
            pr[i] = ch-'0';
            i++;
    }
    for(j=0; j<i; j++)
        printf("pr[%d]: %d\n", j, pr[j]);
    return 0;
}

My code cannot recognize the contiguous number. just ' pr ' array has {3, 4, 2, 1, 3, 4, 2, 5, 6, 1, 0, 3, 4, 0, 0, 5} . Is there any method to implement my objective?

That is algorithm:

  • Use a string to store current number. At first, init it as empty string
  • when ch is a digit('0'..'9'), put it in this string
  • when ch is not a digit, if string is not empty, convert current string to number by atoi function, and store that number in array. After that, init current string to empty again.

Ex: i have string "ab34 56d1"

  • use string str to store current number, at first str =""(empty)
  • ch = 'a', do nothing (because current string is empty)
  • ch = 'b', do nothing
  • ch = '3', put it to string, so str = "3"
  • ch = '4', put it to str, now str = "34"
  • ch = ' ', convert "34" to 34, save it in array, init str="" again
  • .....

Create a state machine .

Keep track of the previous character - was it a digit?

When a digit is detected ...
... If continuing a digit sequence, *10 and add
... Else start new sequence

Do not overfill pr[]

Use int ch to properly detect EOF

//char ch;
int ch;
bool previous_digit = false;
int pr[100];
int i = 0 - 1;
while (i < 100 && (ch = getchar()) != '\n' && ch != EOF) {
  if (ch>='0' && ch<='9') {
    if (previous_digit) {
      pr[i] = pr[i] * 10 + ch - '0';
    } else {
      i++;
      pr[i] = ch - '0';
    }
    previous_digit = true;
  } else {
    previous_digit = false;
  }
}
i++;

Here is a working code. I try 3-4 times it works fine. chPrevious will hold the previous state of ch. There is no need to store the digits into the string of digit. We can simply use an integer for this purpose.

#include<stdio.h>
#define NONDIGIT 'a'

int main() {
    char ch, chPrevious; //chPrevious hold the previous state of ch.
    chPrevious = NONDIGIT;
    int temp = 0;
    int pr[100];
    int i = 0;
    while ( (ch = getchar()) != '\n' ){
    if( (ch>='0' && ch<='9') && (chPrevious>='0' && chPrevious<= '9')){
        temp = temp * 10 + (ch - '0');
    } else if (ch>= '0' && ch<= '9' && temp != 0) {
        pr[i++] = temp;
        temp = 0;
        temp = ch - '0';
    } else if (ch >= '0' && ch <= '9') {
        temp = ch-'0';
    }
    chPrevious = ch;
    }
    pr[i++] = temp;
     for(int j=0; j<i; j++)
        printf("pr[%d]: %d\n", j, pr[j]);
    return 0;
}

There may be other way too do to this and efficient also. Please ignore the bad styling. You should also improve this code as well.

Use scanf. Life becomes simpler when you use standard functions instead of making up your own algorithms.

This code uses scan read a line of user input and then parses it. Detected digits are put into an array and the search index is shifted forward by the number of digits.

char line[100];
int p[100];
int readNums = 0;
int readDigits = 0;
int len;
int index = 0;

//get line
scanf("%99[^\n]%n",line,&len);

while( index < len ){
    if(line[index] <= '9' && line[index] >= '0'){
        if(sscanf(line + index, "%d%n", p + readNums, &readDigits) != 1)
            fprintf(stderr, "failed match!!!! D:\n");
        index += readDigits;
        readNums++;
    }
    index++;
}

//print results
printf("read %d ints\n", readNums);

for(int i = 0; i < readNums; i++)
    printf("p[%d] = %d\n", i, p[i]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM