Digamos que tengo una cadena como ab234cid*(s349*(20kd
y quiero extraer todos los números 234, 349, 20
Qué tengo que hacer ?
¿Cómo extraer números de una cadena en c?
Serguéi Kalinichenko
Puedes hacerlo con strtol
Me gusta esto:
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++;
}
}
Enlace a idea.
-
+1: pero porque
long long val = strtol();
? Prefiero usar C99strtoll()
o definir val comolong
🙂– pmg
15 de noviembre de 2012 a las 14:39
-
En realidad, dado que no está buscando
-
Me gustaríaunsigned long
ystrtoul
. =)– Esteban Canon
15 de noviembre de 2012 a las 14:40
-
@HappyGreenKidNaps Eso es lo que hace que el segundo parámetro de
strtol
tan útil.– Serguéi Kalinichenko
15 de noviembre de 2012 a las 14:42
-
@HappyGreenKidNaps: si la llamada no tiene éxito porque no hay ningún dígito presente, el valor de
p
no será cambiado por la llamada (o mejor dicho, se actualizará con el mismo valor que tenía anteriormente).– Esteban Canon
15 de noviembre de 2012 a las 15:41
-
¿Qué tal si tiene un número negativo, digamos ab-234cid*?
– Raulp
12 de marzo de 2015 a las 10:20
hmjd
Una posible solución usando sscanf()
y conjuntos de escaneo:
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);
}
donde %*[^0123456789]
significa ignorar la entrada hasta que se encuentre un dígito. Ver demostración en http://ideone.com/2hB4UW .
O, si se desconoce la cantidad de números, puede usar %n
especificador para registrar la última posición leída en el búfer:
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);
}
-
La cadena proporcionada es arbitraria, esto puede no funcionar bien con un número aleatorio de enteros. ¡Gracias de cualquier manera!
– CDT
16 de noviembre de 2012 a las 13:13
-
@CDT, el segundo fragmento lo hace.
– hmjd
16 de noviembre de 2012 a las 13:37
-
¿Por qué no funciona para la entrada?
234cid*(s349*(20kd
?– Sathyamoorthy R
31/10/2017 a las 20:43
-
Esto no funciona para números positivos.
– Mattwmaster58
11 de diciembre de 2021 a las 1:36
aquí después de una solución simple usando sscanf
:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str[256]="ab234cid*(s349*(20kd";
char tmp[256];
int main()
{
int x;
tmp[0]='\0';
while (sscanf(str,"%[^0123456789]%s",tmp,str)>1||sscanf(str,"%d%s",&x,str))
{
if (tmp[0]=='\0')
{
printf("%d\r\n",x);
}
tmp[0]='\0';
}
}
Cree una máquina de estado que opere con un principio básico: el carácter actual es un número.
- Al pasar de no dígito a dígito, inicializa su número actual: = número.
- al pasar de un dígito a otro, “cambia” el nuevo dígito en:
numero_actual := numero_actual * 10 + numero; - al pasar de dígito a no dígito, genera el número_actual
- cuando de no dígito a no dígito, no haces nada.
Las optimizaciones son posibles.
Si los números están separados por espacios en blanco en la cadena, puede usar sscanf(). Como no es el caso con su ejemplo, debe hacerlo usted mismo:
char tmp[256];
for(i=0;str[i];i++)
{
j=0;
while(str[i]>='0' && str[i]<='9')
{
tmp[j]=str[i];
i++;
j++;
}
tmp[j]=0;
printf("%ld", strtol(tmp, &tmp, 10));
// Or store in an integer array
}
Félix
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
void main(int argc,char *argv[])
{
char *str ="ab234cid*(s349*(20kd", *ptr = str;
while (*ptr) { // While there are more characters to process...
if ( isdigit(*ptr) ) {
// Found a number
int val = (int)strtol(ptr,&ptr, 10); // Read number
printf("%d\n", val); // and print it.
} else {
// Otherwise, move on to the next character.
ptr++;
}
}
}
Divyanshu Kushwaha
O puede hacer una función simple como esta:
// Provided 'c' is only a numeric character
int parseInt (char c) {
return c - '0';
}
-
Si decide responder una pregunta anterior que tiene respuestas correctas y bien establecidas, es posible que agregar una nueva respuesta tarde en el día no le dé ningún crédito. Si tiene alguna información nueva distintiva, o está convencido de que las otras respuestas son incorrectas, agregue una nueva respuesta, pero ‘otra respuesta más’ que brinda la misma información básica mucho tiempo después de que se formuló la pregunta por lo general no t ganar mucho crédito.
–Jonathan Leffler
02/09/2017 a las 22:53
(1) ¿Qué has intentado hasta ahora?, y (2) ¿estás familiarizado con esdigito()
– WhozCraig
15 de noviembre de 2012 a las 14:32
Lo hace
-123
contar como un número?+123
?–Keith Thompson
30 mayo 2015 a las 0:00