Sequence reading of numbers separated by space

2

It is necessary to read only one line with a set of integers separated by space, each item separated by space will be inserted in a linked list: 1 41 2 15 6 7 87 4 2 1 9 0

List would be something like = [1, 41, 2, 15, 6, 7, 87, 4, 2, 1, 9, 0]

Example:

$ gcc example.c -o example -g -Wall 
$ ./example 
1 41 2 15 6 7 87 4 2 1 9 0<enter>

The biggest problem is that the number of numbers that will come into the input is undefined, that is, the input can also be: 1 8 6

Lista = [1, 8, 6]

Because the quantity is undefined, I thought of two possible solutions:

  • a) scanf ("%[^\n]%*c", sequenciaNumeros);
  • b) Use fgets

In both cases, I would have the problem of declaring a huge array of characters to ensure that it does not reach the limit.

If the quantity was defined it would be simple:

scanf("%d %d %d, &valor1, &valor2, &valor3)

Is it possible with scanf to pick up this line and be able to manipulate each of the numbers (which are separated by space) to add to the list, knowing that the number of numbers can vary ? The entry is mandatory only one row of a set of numbers separated by space

    
asked by anonymous 03.09.2016 / 18:13

3 answers

1

You can use scanf() , because with it you can distinguish the numbers from each other.

To solve your problem, one possible way is to read one number at a time and at each reading, dynamically allocate enough memory to read that number, using malloc() . For this you would need a structure that expands its size dynamically. This avoids the problem of:

  • Statically allocate a vector too small and can not store all the data.
  • Statically allocate a very large vector, wasting space in memory.
  • A data structure that assists you in this is a linked list . An alternative can be a dynamic array.

    Either way you need to define an end identifier. Some character that will dictate when the sequence ends. If it is a sequence of integers, you can use a negative character to indicate the end of the sequence. For example, -1 . Or EOF .

    But , the following reflection might fit here: Is it necessary for all numbers to be in memory at once?

    A very simple example to illustrate this scenario is a accumulator .

    Scenario: Imagine that a program is requested to add up all the numbers that the user types. Solution: One approach is to save all of them in memory and then iterate in them, adding them up. A simpler approach would be to just make an accumulator:

    soma = soma + numero_da_entrada;

    I hope I have helped!

    Issue 1 : Apparently, you can use% return of% to know when there are no more numbers to read:

    int numero;
    while(scanf("%d", &numero) == 1) { // scanf retorna 1 quando a leitura for bem sucedida
        printf("%d", numero);
    }
    

    Issue 2 : To read the entire line and stop when you press enter:

    int numero;
    char proxChar;
    while(scanf("%d%c", &numero, &proxChar) == 2) { 
            printf("%d", numero);
            if(proxChar == '\n') break; 
    }
    
        
    03.09.2016 / 18:36
    1

    Read only one number at a time. The result of scanf will then be 1 if the reading was successful, or zero if it failed, and in this case the line was read through.

    For each number read, allocate space dynamically with malloc. Use a linked list to store the read numbers.

        
    03.09.2016 / 18:45
    0

    You can use fgets to pick up the entry and strtok to break into parts:

    char entrada[100];   // Para obter até 100 caracteres da entrada
    int * elementos[10]; // Array com capacidade para 10 elementos
    int i = 0;
    
    int tamanhoArray = sizeof elementos / sizeof(int);
    
    if(fgets(entrada, sizeof entrada, stdin) != NULL) {
        for (char *pedaco = strtok(entrada, " "); pedaco != NULL; pedaco = strtok(NULL, " ")) {
    
            // Se atingir a capacidade do array
            if (i >= tamanhoArray) {
                puts("Não foi possível adicionar mais itens na lista!");
                break;
            }
            elementos[i++] = pedaco;
        }
    
        for (int n = 0; n < tamanhoArray; ++n) {    
            printf("Indice [%d] = %s\n", n, elementos[n]);
        }
    } 
    

    See DEMO

    If you prefer to create array with size based on the number of spaces:

    char entrada[100];  // Para obter até 100 caracteres da entrada
    int qtdEspacos = 1;
    int i = 0;
    
    if(fgets(entrada, sizeof entrada, stdin) != NULL) {
        char *ptr = entrada;
    
        while((ptr = strchr(ptr, ' ')) != NULL) { // Se encontrou espaço
            qtdEspacos++;
            ptr++;
        }
    
        // Cria o array com tamanho baseado na quantidade de espaços na string
        int * elementos[qtdEspacos];
    
        for (char *pedaco = strtok(entrada, " "); pedaco != NULL; pedaco = strtok(NULL, " ")) {
            elementos[i++] = pedaco;
        }
    
        for (int n = 0; n < qtdEspacos; ++n) {    
            printf("Indice [%d] = %s\n", n, elementos[n]);
        }
    }
    

    See DEMO

        
    03.09.2016 / 20:09