Guardar una linea de enteros separados por un espacio en C

Iniciado por FERNIIIIN, 6 Noviembre 2018, 19:51 PM

0 Miembros y 1 Visitante están viendo este tema.

FERNIIIIN

Buenas dias/tardes/noches a todos tengo un problema en el que espero que me puedan ayudar.

Necesito guardar un serie de números enteros que están separados por un espacio en un arreglo, es decir, me dan un número N que la longitud de mi arreglo A[N] y la siguiente entrada son N números que debo guardar en A, ejemplo:

5
1 3000 466 588 57778


Mi duda es como guardarlos, si estuvieran juntos los números o los ingresaran un seguido de otro seria fácil, pero de esta forma no se me ocurre que hacer.

Gracias a todo los que puedan darme unas ideas que implementar.

MAFUS


FERNIIIIN

Cita de: MAFUS en  6 Noviembre 2018, 20:05 PM
Intenta con strtok

Tengo esto escrito pero no me deja avanzar en el GETS

int main() {
int  total = 0, N, M;
char **arreglo = NULL;
char *buffer; // donde se guarda todo el texto
char *token = NULL;

  scanf("%d %d", &N, &M);
  gets (*buffer);
  printf("%s\n", *buffer);

token = strtok(*buffer,",");
while(token != NULL) {
arreglo = realloc(arreglo, sizeof(char*) * (total +1));
arreglo[total] = token;
printf("Nombre %i: %s\n",total+1,arreglo[total]);
total++;
token=strtok(NULL,",");
}
}


Alguien me podría decir ¿en que me estoy equivocando?

AlbertoBSD

En algun punto copiaste el codigo de algun lado y no sabes que hace  tal o cual linea.

Aqui un ejemplo funcional que publique hace unos dias, posiblemente copiasta algo de ahi... o alguien copio algo de ahi, publico el codigo y tu copiaste algo de ese codigo resultante en fin

https://foro.elhacker.net/programacion_cc/leer_archivo_csv-t489183.0.html


  scanf("%d %d", &N, &M);
  gets (*buffer);


Esa linea no tiene ningun sentido, Lees algo mediante scanf, y luego usas la funcion gets, En primera tienes que usar Scanf o gets, no puedes usar los 2 asi tal cual.
En segunda el gets esta mal escrito deberia de ser

gets (buffer);

Tercera buffer NO ESTA INICIALIZADO EN NINGUN LADO.


Ahora la parte de

strtok(*buffer,",");


Tambien esta mal escrita, no lleva el *,

y si quieres tealizar un tokenize mediante Espacios, deberias de usar " ", en lugar de ","

Dame unos minutos y te publico tu codigo. como debe de ser
que tambies es para leer, sin embargo esta mal escrita
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

AlbertoBSD

Salida:


C:\codigos>tsss.exe
10
1 2 3 5 5 5 5 5 5 5
Numero 1: 1
Numero 2: 2
Numero 3: 3
Numero 4: 5
Numero 5: 5
Numero 6: 5
Numero 7: 5
Numero 8: 5
Numero 9: 5
Numero 10: 5



Codigo


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main() {
int  N,i = 0,len;
char **arreglo = NULL;
char *buffer;
char *token = NULL;
char temporal[1000];
fgets(temporal,1000,stdin);
N = strtol(temporal,NULL,10);
token = strtok(buffer," ");
fgets(temporal,1000,stdin);
token = strtok(temporal," ");
do {
arreglo = realloc(arreglo, sizeof(char*) * (i +1));

//arreglo[i] = token; // Esta linea esta bien, pero realmente recomiendo moverl el contenido de esta posicion de memoria a uno que si controlemos nosotros
len = strlen(token);
arreglo[i] = calloc(len+1,sizeof(char));
memcpy(arreglo[i],token,len);
printf("Numero %i: %s\n",i+1,arreglo[i]);
token = strtok(NULL," ");
i++;
}while(i < N && token != NULL);
}


Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

FERNIIIIN

Cita de: AlbertoBSD en  7 Noviembre 2018, 01:59 AM
Salida:


C:\codigos>tsss.exe
10
1 2 3 5 5 5 5 5 5 5
Numero 1: 1
Numero 2: 2
Numero 3: 3
Numero 4: 5
Numero 5: 5
Numero 6: 5
Numero 7: 5
Numero 8: 5
Numero 9: 5
Numero 10: 5



Codigo


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main() {
int  N,i = 0,len;
char **arreglo = NULL;
char *buffer;
char *token = NULL;
char temporal[1000];
fgets(temporal,1000,stdin);
N = strtol(temporal,NULL,10);
token = strtok(buffer," ");
fgets(temporal,1000,stdin);
token = strtok(temporal," ");
do {
arreglo = realloc(arreglo, sizeof(char*) * (i +1));

//arreglo[i] = token; // Esta linea esta bien, pero realmente recomiendo moverl el contenido de esta posicion de memoria a uno que si controlemos nosotros
len = strlen(token);
arreglo[i] = calloc(len+1,sizeof(char));
memcpy(arreglo[i],token,len);
printf("Numero %i: %s\n",i+1,arreglo[i]);
token = strtok(NULL," ");
i++;
}while(i < N && token != NULL);
}


Saludos!

Muchas gracias, ayer tenia prisa y confundí el código con un ejercicio similar pero con mas entradas.
Un amigo me estaba ayudando y me mando parte del código, tal vez y si lo copio, pero como tenia prisa no pudo explicarme bien que había hecho.

Una ultima pregunta, ¿sabes si hay una función para pasar el valor que esta guardando el doble puntero (arreglo) a un array?

Es decir, algo así como:
**arreglo= arr[j]

FERNIIIIN

Basándome en parte de lo que creaste "AlbertoBSD" yo estoy haciendo otro, para ver si soy capaz de simplificarlo. En la noche lo subo.

SALUDOS. ;D

AlbertoBSD

Pues técnicamente el "arreglo" es un Arrglo,

Es un arreglo de apuntadores que apuntan valga la redundancia a donde estan guardados los valores leídos

Si ves en las lineas


arreglo[i] = calloc(len+1,sizeof(char));
memcpy(arreglo[i],token,len);
printf("Numero %i: %s\n",i+1,arreglo[i]);


Siempre se hace referencia a arreglo.



Tal vez lo que necesitas es un arreglo Fijo, pero al no conocer que te van a dar como N , no podras por metodos de arreglos fijos prevenir correctamente el valor de N

char arreglo[N][30];

Supongamos un N = 1000


Ejemplo:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main() {
int  N,i = 0,len;
char *buffer;
char *token = NULL;
char temporal[5000];
fgets(temporal,1000,stdin);
N = strtol(temporal,NULL,10);
char arreglo[N][30];
token = strtok(buffer," ");
fgets(temporal,5000,stdin);
token = strtok(temporal," ");
do {
//arreglo[i] = token; // Esta linea esta bien, pero realmente recomiendo moverl el contenido de esta posicion de memoria a uno que si controlemos nosotros
len = strlen(token);
memcpy(arreglo[i],token,len);
printf("Numero %i: %s\n",i+1,arreglo[i]);
token = strtok(NULL," ");
i++;
}while(i < N && token != NULL);
}


Salida para N = 10


C:\codigos>ts1.exe
10
1 2 3 4 5 6 7 8 9 0
Numero 1: 1
Numero 2: 2
Numero 3: 3
Numero 4: 4
Numero 5: 5·a
Numero 6: 6
Numero 7: 7fúw~
Numero 8: 8
Numero 9: 9ÖÖ
Numero 10: 0



Salida para N=1000


Numero 961: 1
Numero 962: 2w╕τa
Numero 963: 3æ╝w Φa
Numero 964: 4
Numero 965: 5τa
Numero 966: 6w
Numero 967: 7@8
Numero 968: 8⌠
Numero 969: 9
Numero 970: 0µ
Numero 971: 1
Numero 972: 2
Numero 973: 3
Numero 974: 4
Numero 975: 5Θa
Numero 976: 6
Numero 977: 7
Numero 978: 8
Numero 979: 9ó╛wƱOuÉ
Numero 980: 0
Numero 981: 1
Numero 982: 2
Numero 983: 3
Numero 984: 4
Numero 985: 5
Numero 986: 6
Numero 987: 7
Numero 988: 8
Numero 989: 9Ωa
Numero 990: 0
Numero 991: 1Ωa
Numero 992: 2w
Numero 993: 3Ēw
Numero 994: 4
Numero 995: 5╝íw
Numero 996: 6
Numero 997: 7
Numero 998: 8
Numero 999: 9
Numero 1000: 0



Le memoria se podria limpiar con

char arreglo[N][30] = {0};

pero se me hace ineficiente hacerlo de esta forma.

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

elgilun

#8
Acá se reserva memoria para la cadena de entrada y para el array de números (ints)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 32 /* supone hasta 32 dígitos para cada número */

int main()
{
    int size;    /* cantidad de números a ingresar */
    char *nums;  /* cadena de texto con los números de entrada */
    int *arr;    /* array de char* para la serie de números resultante */
    char *p;     /* referencia para strtok */
    int i;       /* índice del array */

    scanf("%d ", &size);

    nums = (char*)malloc(N * size); /* cada numero podría ser de N-1 dígitos */
    fgets(nums, N*size, stdin);

    arr = (int*)malloc(size * sizeof(int)); /* espacio para size ints */


    i = 0;
    p = strtok(nums, " ");
    while (p != NULL) {
        arr[i] = atoi(p); /* guarda cada número como int */
        i++;
        p = strtok (NULL, " ");
    }


    /* muestra el array */
    for(i = 0; i<size; ++i) {
        printf("%d) %d\n", i, arr[i]);
    }
    free (arr); /* liberar la memoria del array */
    free(nums); /* y libera la memoria de la cadena de entrada */

    return 0;
}


AlbertoBSD

Excelente!  ;-)

Ahhhh!, arreglo de Enteros. si convertirlos mediante atoi esta bien. Suponiendo que siempre sea un numero valido. La otra funcion mas rubusta es strtol().

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW