-1

I have to read from a file multiple records(each components of the records are separated by a comma), and I can't understand what's the problem, so here's my file:

Rossi,Mario,M,mariorossi@gmail.com,3923333332,Portiere Bianchi,Giuseppe,M,giuseppebianchi@gmail.com,3470000021,Attaccante Ferrari,Anna,F,annaferrari@gmail.com,3466482645,Attaccante Romano,Antonio,M,antonioromano@gmail.com,3450394672,Centrocampista

and here's my code:

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

struct dati_giocatori {
    char cognome[20];
    char nome[20];
    char genere[20];
    char email[50];
    char telefono[16];
    char ruolo[20];
};

typedef struct dati_giocatori GIOCATORE;

void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa);

int main (){

    FILE *pfile;
    GIOCATORE *vettore;
    int dim=0;
    char stringa[200];


        printf("Quanti giocatori vuoi visualizzare?");
        scanf("%d",&dim);
        vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE));

        pfile=fopen("Giocatori.txt","r");  

        stampa_file(pfile,vettore,dim,stringa);
        system("pause");
        fclose(pfile);

        pfile=fopen("Giocatoriv.txt","r");
        system("pause");

        free(vettore);
        fclose(pfile);
        system("pause");

    return 0;
    system("pause");
}

void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa){
    int i=0;
    int j=0;

    if(pfile!=NULL){
     if(!feof(pfile)){
        while(i<dim){
            if(!feof(pfile)){
                fgets(stringa,200,pfile);
                    sscanf(stringa,"%[^,],%[^,],%[^,],%[^,],%[^,],%s",vettore[i].cognome,vettore[i].nome,
                            vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
                i++;
                }
                else{
                    printf("\n----- Giocatori finiti -----\n");
                    printf("\n");
                    i=dim;
                }
            }
        }
     else{
         printf("\nFile finito.\n");
     }

    }
    else{
        printf("Errore nell'apertura del file.\n");
        printf("\n");
    }

     while(j<dim){
            printf("%s,%s,%s,%s,%s,%s\n",vettore[j].cognome,vettore[j].nome,
                  vettore[j].genere,vettore[j].email,vettore[j].telefono,vettore[j].ruolo);
            j++;
                    }   
    system("pause");
}

I know the problem is with the sscanf(), because it prints on screen just the first component of every record, and five commas, but I can't figure out how to solve this problem... It does not assign the right data to the right place on the records, is the sscanf() format correct? I am not very familiar with delimiters, how should I fix this?

Thanks everyone for helping. I'm sorry you waited so long for the response but I could not edit yesterday. I'm really sorry also for the posting errors, I'm new at stack overflow and I'm also new in C (it's my first language)...(and just to make it difficult to me, I'm also not a native speaker as you can notice by my grammar errors). Yes the email addesses are fake. By the way, I'm gonna be honest I don't know hot to check if the file has a newline character at the end of every record...While writing the file I thought that pressing "enter" would gave to me the newline character, but reading you comments I am not sure anymore. I want to use newline character at the end of every record, but how do I do that? and, will this make my code work? (I opened a second time the file because I was just trying other things on it, so please don't mind about that, same for the system pause).

Varkas
  • 1
  • 3
  • 4
    Your use of `if (!feof(...))` is no better than `while (!feof(...))`, [which is wrong](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Some programmer dude Jun 01 '17 at 15:27
  • 5
    I hope you posted fake email addresses in your example file... – ryyker Jun 01 '17 at 15:36
  • Are there newlines at the end of each record? (There are not in what you have posted). – ad absurdum Jun 01 '17 at 15:52
  • Does the file contain newlines? – BLUEPIXY Jun 01 '17 at 16:15
  • 2
    Post the exact input used and the exact output seen. – chux - Reinstate Monica Jun 01 '17 at 16:16
  • You need to provide the extra information we ask for if you want help with this. I can't reproduce your problem. Despite numerous issues with posted code, it appears to "work" for the sample file, if there are terminating newlines for each record. If not, the code prints the first record, then garbles remaining records. – ad absurdum Jun 01 '17 at 17:02
  • thank you guys so much, I tried to edit my first post, ask me anything you want to know – Varkas Jun 02 '17 at 09:01
  • @Varkas-- look at your actual file `Giocatori.txt` in a text editor. When I copy/paste what you have posted into a text editor, there is only one long line of text. If there are newlines, you should see 4 lines of text. As I said in my comment above, your code works for me when I copy/paste your example and add the newlines (by pressing ENTER at the end of each line). But, even without the newlines, your code failed, but not exactly in the way you described. This is why we ask for your _exact_ input and _exact_ output. Use copy/paste, and use a code-block instead of block-quotes for text file. – ad absurdum Jun 02 '17 at 12:30

1 Answers1

1

Okay, first of all next time make your question and specially your code more readable (you must use indentation properly). I don't understand why you use so many system("pause"); also in a wrong way. You also cast the result of vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE)); and you should not do it. You open the file, then use it, close it and open a new file doing nothing on it so I removed this. Note that using while (!feof(file)) is always wrong. Then in your stampa_file function I made lots of changes.

Here is the code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * NOTE: I'M NOT CHECKING **ANY** RETURNING ERROR
 * SUCH AS FROM FOPEN OR MALLOC.
 */
struct dati_giocatori {
    char cognome[20];
    char nome[20];
    char genere[20];
    char email[50];
    char telefono[16];
    char ruolo[20];
};

typedef struct dati_giocatori GIOCATORE;

void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa);

int main (){
    FILE *pfile;
    GIOCATORE *vettore;
    int dim=0;
    char stringa[200];
    printf("Quanti giocatori vuoi visualizzare?");
    scanf("%d",&dim);
    vettore= malloc(dim*sizeof*vettore);
    pfile=fopen("Giocatori.txt","r");  
    stampa_file(pfile,vettore,dim,stringa);
    fclose(pfile);
    return 0;
}

void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa){
    int i=0;
    int j=0;
    size_t size = 200;
    if(pfile!=NULL){
            while((getline(&stringa, &size, pfile)) != -1 && i<dim) {
                sscanf(stringa,"%[^,],%[^,],%[^,],%[^,],%[^,],%s",vettore[i].cognome,vettore[i].nome,
                            vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
                i++;
            }
    }
    printf("No more records to read\n");
    while(j<i){
        printf("%s,%s,%s,%s,%s,%s\n",vettore[j].cognome,vettore[j].nome,
                  vettore[j].genere,vettore[j].email,vettore[j].telefono,vettore[j].ruolo);
        j++;
      }
    if(dim > i){
        printf("Not enough players\n");
    }   
}

That's the file I used for tests:

Rossi,Mario,M,mariorossi@gmail.com,3923333332,Portiere Bianchi,Giuseppe,M,giuseppebianchi@gmail.com,3470000021,Attaccante Ferrari,Anna,F,annaferrari@gmail.com,3466482645,Attaccante Romano,Antonio,M,antonioromano@gmail.com,3450394672,Centrocampista

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
simo-r
  • 733
  • 1
  • 9
  • 13
  • If you would have read [my comment under the OP](https://stackoverflow.com/questions/44311551/fgets-and-sscanf-records-from-file-with-delimitators#comment75632114_44311551), you would have seen that OP code appears to work if the text file contains newlines, but not if it does not. Your code also works with newlines, but not without. Until OP answers questions raised in comments, we can't really answer this question effectively. – ad absurdum Jun 01 '17 at 19:25
  • @DavidBowling tell me if I'm wrong. The `getline` reads at least `size` elements or until it finds a `\n` or `EOF`. In the question code he assumes that a line is of `200 characters` so there isn't any problem with `getline`. – simo-r Jun 01 '17 at 19:45
  • 1
    I didn't say that there is a problem using `getline()`. The problem is that OP has not stipulated whether the records are terminated by `\n` characters, and this _will_ affect parsing operations. Posted example does not contain newlines, but looks like it does. What is the truth of the matter? I just double-checked by running your code against the example copy-pasted into a file-- it crashed. OP code appeared to work for me with sensible newlines, which begs the question, what is OP's _real_ problem? Still waiting for them to respond.... – ad absurdum Jun 01 '17 at 20:15
  • Note that I am not saying that OP code is correct, or that your suggestions are bad; just that we don't know enough to _answer_ yet. – ad absurdum Jun 01 '17 at 20:16
  • thank you guys so much, I tried to edit my first post, ask me anything you want to know – Varkas Jun 02 '17 at 09:01
  • @Varkas if you've a new line in every line this code should work. As you can see it reads a line with at most 200 characters. – simo-r Jun 02 '17 at 09:05
  • ok, but how do I put the newlines in the file? (I have the access to the file, I created it) – Varkas Jun 02 '17 at 09:10
  • @Varkas [Take a look here](https://stackoverflow.com/questions/10059142/reading-r-carriage-return-vs-n-newline-from-console-with-getc) – simo-r Jun 02 '17 at 09:20