Read numbers separated by commas

Asked

Viewed 1,420 times

2

I need the sixth figure printed on a arquivo.txt. I tried to read the file and print the first six on the screen to see if it was working, then generate a file with only the value I need organized, given that I need to repeat this process for another 4,000 files, but I’m not even getting that.

The archive txt What I’m trying to read is this:

0.00053714,0.00053714,-0.00061595,0.30794,-0.00061595,0.30794,1.0001,1,0.0050735

Below is the code I made:

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

int main()
{
    FILE *arquivo;
    int i=1;
    float a[6];
    char valor[80],*token, linha;

    arquivo = fopen("arquivo.txt","r");

    if (arquivo = fopen ("arquivo.txt", "r") == NULL)
    {
        printf ("Error opening file\n");

        getch();
    }

    fgets(valor, 80, arquivo);
    printf("STRING ----> %s\n", linha);
    token = strtok(valor,",");
    while(token!=NULL)
    {
        token=strtok(NULL,",");

        if(token!=NULL)
        {
            a[i]=atoi(token);
            i++;
        }
    }

    for(i=1;i<7;i++)
        printf("a[%d] = %f\n", i, a[i]);

    return 0;
}
  • How do you want the output of the program?

  • I would just like to get this sixth value and then print it in a txt file, because I can do it in one, I already have a piece of code ready to read all the files, so I would just add this snippet to it.

  • This 0.30794 would be the sixth value?

  • Yeah, that’s the one.

  • As an example, the contents of your file would be this: 0.00053714,0.00053714,-0.00061595, the output you would want would be this way: 0.00053714 | 0.00053714 | -0.00061595 separating values by comma , that?

  • In fact, I don’t even need the others, only 0.30794, because in the end I will add the sixth value of each file to form a single.

  • Tulio - I know you’ve learned C - and it’s important to learn better - but these kinds of tasks are best done in other languages - which automate details like opening files, allocating strings, cutting strings, etc. A one-line program in Python that does what you are asking is: print (open("[nome_do_arquivo.txt]").read().split(",")[5]) (ended that’s the whole program - save to a "program.py" file and run with python programa.py . To join the data of the 4000 files, a formatted and readable program will have about 10 lines.

  • Actually @jsbueno , this file I’m reading is the result of a Pyton script, but since I haven’t been programming for a long time, I searched what I knew was C, since I didn’t have time to learn Pyton. Thanks for the tip, I will look for material to study this language, because it seems much more practical looking for this aspect.

  • Cool - whatever, my email is in the profile here. Or ask the same question for a Python script that the staff answers. :-)

Show 4 more comments

2 answers

3


Create a program that asks you what is the position of the value (element) you need, and search for this value according to the chosen position, it also separates the values by comma "," as your need expressed in the question.

Let’s take the example, follow the example below:

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

int main(void)
{
    FILE* file = fopen("arquivo.txt", "r");

    char line[256];
    char * valor;
    char * valor_escolhido;

    int cont_elemento = 1, posicao_elemento;

    printf("Informe a possicao ° do valor, (exemplo 1, 2 ou 6): ");
    scanf("%d", &posicao_elemento);

    if (file == NULL)
        return EXIT_FAILURE;

    /*Faz a leitura do arquivo linha por linha.*/
    while (fgets(line, sizeof(line), file))
    {
        /*Pega o primeiro elemento separado por uma virgula.*/
        valor = strtok(line,",");

        /*Obtem os outros elementos até o fim da linha.*/
        while (valor != NULL)
        {
            printf("%s\n",valor);
            valor = strtok(NULL, ",");

            cont_elemento++;

            if (cont_elemento == posicao_elemento)
                valor_escolhido = valor;
        }
    }

    printf("\n\nValor escolhido: %s\n\n", valor_escolhido);

    fclose(file);

    return EXIT_SUCCESS;
}

I used the function strtok that is part of header string.h, it can be used when we need to break a string into C using a delimiter, so that it will return its parts according to the value specified in delimiter which in this case is the comma ,. View the function signature strtok:

char * strtok ( char * str, const char * delimiters );

Explanation of the program.

I assumed that the structure of your file is in the following format according to the contents of the same that was informed in the question, follows the structure of the file that will be the input data:

0.00053714,0.00053714,-0.00061595,0.30794,-0.00061595,0.30794,1.0001,1,0.0050735

The program will ask the value position (element):

Enter the possible ° of the value, (example 1, 2 or 6):

Value I informed you:

6

I chose the 6° (sixth) element, and it will return me the value 0.30794.

Exit from the program.

Based on the input data that was reported to the program in the above example, the program will generate the following output:

0.00053714
0.00053714
-0.00061595
0.30794
-0.00061595
0.30794
1.0001 1
0.0050735

Chosen value: 0.30794

Completion.

To get the chosen value you have to count the number of occurrences issued by the function strtok using the variable cont_elemento, and do the validation to compare to the chosen position in a if, see: if (cont_elemento == posicao_elemento), then just assign the string with the separate value by the function to the string valor_escolhido, so I got the chosen value.

Sources:
Split string in C Every white space.
Split string into tokens.
How to use the Strtok() function to break a C string using delimiters.

  • 1

    Perfect and very well explained. Thank you very much.

  • Beautiful. poetic. But remember, except for teaching purposes, it’s not the kind of program you should do in C.

  • @jsbueno is not a complete solution has to improve a lot in this program, if you have any suggestions for improvement?

  • I would not invest in this program in C - as I said, languages of something else level have a very great facility to handle strings, and read files - mainly dynamic languages. I am good (and fanatic for) Python. I can even write the program in Python below .

  • In your program, without analyzing too deeply, I noticed a security/integrity problem that is typical of when we want to make simple programs in C - you should have a null test right after the call valor = strtok(NULL, ","); - and get out of whileali - and do not use this value if it is NULL - and also an initialization of the variable "chosen value". As it stands, if the read file has fewer elements than expected, you pass an undefined pointer, or NULL to the printf.

  • @jsbueno made the solution according to the need of AP that was in C, however I also preferred to use a high-level language like Python, more for the ease of string manipulation. That mistake you quoted I hadn’t realized.

  • Yes, I understand perfectly. C question, answer in C. See my comment on the question. The ero I mentioned is one of the reasons, in addition to being shorter, to do such programs in high-level languages. In C you have to worry about everything, all the time.

  • @Denercarvalho , I adapted this program for my case, but I can’t get the sixth value of the 4000 files. For some reason, the fgets inside the while is giving Segmentation fault. I can always read up to the 1016 file. I tested on another computer and in the same way, there was Segmentation fault, but in file 1018. I think I should change some parameters to perform this operation several times, but I couldn’t see which one specifically. Do you have any idea?

  • @I don’t know what the purpose of the algorithm you are already using is, if I were you I would use a higher level language for manipulating strings, or ask another question to isolate the problem regarding.

  • 1

    @Thank you, I will post another question, it is easier and organized.

Show 5 more comments

1

awk is almost C

awk -F, '{print $6}' arquivo.txt

Simplified explanation: Internally awk divides each row into fields (in this case the field separator is , due to -F,), each field is assigned a number $1, $2, ...$n just tell us what we want to print.

  • 1

    What does awk -F? got curious

  • @rray -F, means the field separator is ,

  • Type one split by 6 characters?

  • @rray, more or less: I added a brief explanation.

  • 1

    Got it now :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.