You can do it with strtol, like this:
char *str = "ab234cid*(s349*(20kd", *p = str;
while (*p) { // While there are more characters to process...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Found a number
long val = strtol(p, &p, 10); // Read number
printf("%ld\n", val); // and print it.
} else {
// Otherwise, move on to the next character.
p++;
}
}
Link to ideone.
Answer from Sergey Kalinichenko on Stack OverflowYou can do it with strtol, like this:
char *str = "ab234cid*(s349*(20kd", *p = str;
while (*p) { // While there are more characters to process...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Found a number
long val = strtol(p, &p, 10); // Read number
printf("%ld\n", val); // and print it.
} else {
// Otherwise, move on to the next character.
p++;
}
}
Link to ideone.
A possible solution using sscanf() and scan sets:
const char* s = "ab234cid*(s349*(20kd";
int i1, i2, i3;
if (3 == sscanf(s,
"%*[^0123456789]%d%*[^0123456789]%d%*[^0123456789]%d",
&i1,
&i2,
&i3))
{
printf("%d %d %d\n", i1, i2, i3);
}
where %*[^0123456789] means ignore input until a digit is found. See demo at http://ideone.com/2hB4UW .
Or, if the number of numbers is unknown you can use %n specifier to record the last position read in the buffer:
const char* s = "ab234cid*(s349*(20kd";
int total_n = 0;
int n;
int i;
while (1 == sscanf(s + total_n, "%*[^0123456789]%d%n", &i, &n))
{
total_n += n;
printf("%d\n", i);
}
Extract number from a string C - Stack Overflow
Extract numbers from a character string in C - Stack Overflow
C: extract numbers from a string - Stack Overflow
How to extract a number from a string in C - Stack Overflow
There are many ways to parse a string containing numbers. If you expect the string to have a fixed format with 2 integers, the simplest solution is to use sscanf():
#include <stdio.h>
int parse2numbers(const char *str) {
int a, b;
// sscanf returns the number of successful conversions
int n = sscanf(str, "%d%d", &a, &b);
if (n == 2) {
printf("success: a=%d, b=%d\n", a, b);
return 1;
}
if (n == 1) {
printf("failure: only one number provided: a=%d, str=%s\n", a, str);
return 0;
}
if (n == 0) {
printf("failure: invalid format: %s\n", str);
return 1;
}
printf("failure: encoding error: n=%d, str=%s\n", n, str);
return 0;
}
If the string can contain a variable number of integers, you could use strtol() to parse one integer at a time:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
void parse_numbers(const char *str) {
long a;
char *p;
for (;; str = p) {
errno = 0;
// strtol returns a long int
// updates `p` to point after the number in the source string
// sets errno in case of overflow and returns the closest long int
a = strtol(str, &p, 10);
if (p == str)
break;
if (errno != 0) {
printf("overflow detected: ");
}
printf("got %ld\n", a);
}
if (*str) {
printf("extra characters: |%s|\n", str);
}
}
I have not tested it but I think theoretically this should work:
int rows=2, columns=4 // defining length of array
char ch[rows] [columns] = {"1 90"}, {"2 90"}; // creating two dimensional array for sample data
for (int i = 0; i < rows; i++) { // looping throw first dimention
// this only works if data is sorted and there is no missing indexes in between like [1 200] [3 200] will not work but [1 200] [2 200] should
char* index;
if ( ch[i] [0] != itoa(i+1, index, 10) ) // checking if index does not match the row then skip this iteration and move to next one.
continue;
for ( int j = i+2; j<columns; j++) { // looping through second dimension
printf("%c\n", ch[i][j]); // printing that second dimension
}
}
this should work :
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define ML 81
char *changeStr(char *str)
{
char *new = NULL;;
int i = 0;
int length = 0;
/* calulating the size to allocate with malloc for new */
while (str[i])
{
if (str[i] >= 48 && str[i] <= 57)
length++;
i++;
}
/* if no numbers found, return new which is NULL */
if (length == 0)
return new;
new = malloc(length * sizeof(char));
i = 0;
length = 0;
/* filling new with numbers */
while (str[i])
{
if (str[i] >= 48 && str[i] <= 57)
{
new[length] = str[i];
length++;
}
i++;
}
new[length] = 0;
return new;
}
/* I kept the functions you are using in the main, i would not
use gets, but it's maybe easier for you to keep it */
int main()
{
char str[ML]={0};
char *New;
printf("Enter string: \n");
gets(str);
New = changeStr(str);
if(!New){
printf("No changes in string.\n");
}
else
{
printf("Changed string:\n");
printf("%s",New);
}
return 0;
}
is that , what you wanted ?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MK 20
#define ML 81
void changeStr(char str[],char New[])
{
int i,iNew = 0;
int lenStr = strlen(str);
for(i=0;i<lenStr;i++)
if ( str[i]>= '0' && str[i]<= '9')
New[iNew++]=str[i];
New[iNew]=NULL;
}
int main()
{
char str[ML],New[ML]= {0};
printf("Enter string: \n");
gets(str);
changeStr(str,New);
if(New[0] == '\0')
{
printf("No changes in string.\n");
}
else
{
printf("Changed string:\n");
printf("%s",New);
}
return 0;
}
You could try something like this:
- Walk the string until you find the first digit (use
isdigit) - Use
strtoulto extract the number starting at that positionstrtoulreturns the number- the second argument (
endptr) points to the next character in the string, following the extracted number
- Rinse, repeat
Alternatively you could tokenize the string (using "(,+)") and try to strtoul everything.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main() {
int arr[10], idx=0, d, l=0;
char *p, *str = "Trim(2714,8256)++Trim(10056,26448)++Trim(28248,49165)";
for (p = str; *p != 0; p+=l) {
l = 1;
if (isdigit(*p)){
sscanf(p, "%d%n", &d, &l);
arr[idx++] = d;
}
}
for (l=0; l<idx; l++) {
printf("%d\n", arr[l]);
}
return 0;
}
char date[]="20-02-2015";
int d,m,y;
sscanf(date,"%d-%d-%d",&d,&m,&y);
Assuming that your string is given as char* str or as char str[], you can try this:
int day,mon,year;
sscanf(str,"%d-%d-%d",&day,&mon,&year);
Or you can try this, for a slightly better performance (by avoiding the call to sscanf):
int year = 1000*(str[6]-'0')+100*(str[7]-'0')+10*(str[8]-'0')+(str[9]-'0');
You can use strtok() to extract the two strings with space as an delimiter.
Online Demo:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] =".Word 40";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
return 0;
}
Output:
Splitting string ".Word 40" into tokens:
.Word
40
If you want the number 40 as a numeric value rather than a string then you can further use
atoi() to convert it to a numeric value.
You can use sscanf to extract formated data from a string. (It works just like scanf, but reading the data from a string instead of from standard input)
A combination of digit filtering and sscanf() should work.
int GetNumber(const char *str) {
while (!(*str >= '0' && *str <= '9') && (*str != '-') && (*str != '+') && *str) str++;
int number;
if (sscanf(str, "%d", &number) == 1) {
return number;
}
// No int found
return -1;
}
Additional work needed for numbers that overflow.
A slower, but pedantic method follows
int GetNumber2(const char *str) {
while (*str) {
int number;
if (sscanf(str, "%d", &number) == 1) {
return number;
}
str++;
}
// No int found
return -1;
}
scanf tries to match a pattern.... so if you knew the string was "He is 16 years old." where 16 was an integer number you wished to decode.
( I think your input string implies your format is somewhat free form. I'm assuming its predictable. )
{
char* inputstr = "He is 16 years old.";
int answer = 0;
int params = sscanf (inputstr, "He is %d years old.", &answer);
if (params==1)
printf ("it worked %d",answer);
else
printf ("It failed");
}
I want to convert a string like "180.55.122" into integers in a way so that I would get 180,55 and 122. I thought i could use stoi() but i wont be able to specify the start and end index of what part of the string to convert. Any advice is a
You can use the following algorithm:
- Initialise result to 0
- Iterate over characters of the string
- If character is in the range
['0', '9']then- Multiply the previous result with 10 (this is a decimal shift left)
- Convert the character to the numeric value of the digit
- Add the numeric value to the result
- If character is in the range
Bonus answer (I know OP removed [c++] tag): While the algorithm can be directly translated from natural language, it can be simplified in C++.
accumulate(begin(str), end(str), 0, {
return isdigit(c)
? r*10 + (c - '0')
: r;
});
unsigned int IntegerFromString(unsigned char* str)
{
unsigned int num = 0;
for(unsigned int i = 0 ; i<strlen(str) ; i++){
if(isdigit(str[i])){
num *= 10;
num += (str[i] - 48);
}
}
return num;
}