Parsear números desde cadena de chars en C.

Imagen de danirolo7
0 puntos

Buenas tardes a todos.

Veréis, tengo un pequeño problema en mis aprendizajes de C de un problema que en Java se resuelve en dos líneas.

La idea del asunto es que dada una secuencia de caracteres acabada en '#' hay que obtener (imprimir) los números que aparezcan en ella y su suma. Por ejemplo: "esto es un tex100to de prueba y 74 además 13.82 termina con el símbolo #" La salida sería: 100 74 13.82, suma:187.82.

Lo he intentado de varias formas:

-primera: verificando caracter a caracter si era un número en ASCII (>='0' && <='9') y restándole '0',luego,si en el siguiente espacio del vector había un número también (misma comprobación) el numero actual lo multiplico por 10 y le sumo el numero siguiente.
-segunda: usando un const char* string y usando la función sscanf para buscar los floats que haya en la cadena y pasándolos a otras variables que luego se suman.
-tercera: a lo bestia, con ifs por todas partes y para cada número.

Con la primera me salen sumas alocadas, igual que con la tercera. Con la segunda forma he obtenido los números correctos o directamente termina el programa justo después de leer el vector.

Si queréis, os puedo enseñar muestras de código de las tres formas, pero creo que de poco servirían.

Para finalizar y una vez descrito el problema: alguien puede ayudarme con un algoritmo,lectura recomendada o snippet -trozo de código- para sacar la cuestión? Muchísimas gracias de antemano :)

Perdón por la longitud.

Imagen de cousteau
+1
0
-1

Yo haría algo como

char *p = linea;
do {
    res = sscanf(p, "%[^0-9#]%f%n", basura, &x, &n);
    printf("Resultado: %f | Leídos: %d | Salida: %d\n", x, n, res);
    p += n;
} while (res > 1);

A saber:
%[^0-9#] lo que hace es leer un montón de caracteres que no sean ni 0,1,2...9 ni #, y lo escribe en el array "basura" (cuya salida la descartas).
%f lee el número (float; usa %lf para double) y lo guarda en x. Lee tantos caracteres como tengan sentido.
%n no lee nada, sólo escribe en n el número de caracteres leídos. Después se lo sumo al puntero p para que avance n posiciones, hasta después del número.
El ciclo se repite hasta que sscanf no es capaz de leer el 2º dato (x), momento en el cual res <= 1.

+1
0
-1

«E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem» significa que dpkg se ha interrumpido y que tienes que ejecutar "sudo dpkg --configure -a" para corregir el problema.
Imagen de danirolo7
+1
0
-1

Eres un crack!

Muchísimas gracias! Lo que me faltaba era el %[^0-9#] que generaliza y simplifica una barbaridad :).

De momento el único fallo que tengo es que el último número se repite, pero a eso ya le buscaré yo una solución.

Gracias de nuevo!

+1
0
-1

----------------------------------------------------
Sin malos rollos.

http://fausto23.wordpress.com

Linux User #476658
Ubuntu User#23611

¡¡¡Salud y Libertad!!!

Imagen de cousteau
+1
0
-1

Puedes poner algo como if (res <= 1) break; y después hacer algo con x para que sea definitivo.

char *p = linea;
for (;;) {
    res = sscanf(p, "%[^0-9#]%f%n", basura, &x, &n);
    if (res <= 1) break;
    printf("Resultado: %f | Leídos: %d | Salida: %d\n", x, n, res);
    p += n;
}

(A lo mejor hay que hacer algo en caso de que la línea empiece por número)

+1
0
-1

«E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem» significa que dpkg se ha interrumpido y que tienes que ejecutar "sudo dpkg --configure -a" para corregir el problema.