0

what the code actually does, is storing the whole line into utenti[i].username so let's say in the file we got "Pierluigi,Pierluigi@gmail.com,1983,messicana,30,6.5" the whole line will be stored into utenti[i].username even though username max lenght is 20, obviously that wasn't the original purpose of the code, what is intended to do is to store each value into the right variables. I already used this kind of fopen and fscanf code in another one and it actually works, it stores the data in the right variables, but here it wont work. i was trying to understand why it doesn't work but i cant figure it out, so i'm asking here for help.

#include <stdio.h>
#include <stdlib.h>
#include "mystruct.h"//where i get my structures 

#define MAX_DIM 1000

utente utenti[MAX_DIM];

int main()
{
    FILE *utente;
    int i = 0;
    
    if ((utente = fopen("./Dati/utenti.csv", "r")) == NULL)
                 printf("Impossibile aprire il file.\n");
             else{
                   while(!feof(utente)){
                   fscanf(utente,"%s,%s,%d,%s,%f,%f", utenti[i].username, utenti[i].email, &utenti[i].n_anno, utenti[i].tradizione, &utenti[i].fasciadiprezzo, &utenti[i].media_voti);
                  printf("utenti : %s\n", utenti[i].username);
                  i++;
                }
         }
         fclose(utente);
         return 0;
}

and here's the struct contained in mystruct.h

typedef struct utente{
   char username[20];
   char email[30];
   int  n_anno;//anno di nascita
   char tradizione[20];
   float fasciadiprezzo;
   float media_voti;
   struct prenotazione *p_prenotabili;
   struct recensione *valutazioni;
}utente;

where "prenotazioni ..." and "recensione ..." are linked list

im programming with vs_code

dario3004
  • 21
  • 6

2 Answers2

4

The problem is with your format string:

fscanf(utente,"%s,%s,%d,%s,%f,%f", 
              utenti[i].username, utenti[i].email,
              &utenti[i].n_anno, utenti[i].tradizione,
              &utenti[i].fasciadiprezzo, &utenti[i].media_voti);

The %s format specifier reads all non-whitespace characters. Since commas and digits are not whitespace, they are all read by the first %s.

Instead of %s, you want to use %[. This allows you to specify a set of characters to capture or not capture. Since you want to read everything up to a comma, you want %[^,]. There should also be a space at the start of the format string to absorb any newlines from the prior line.

fscanf(utente, " %[^,],%[^,],%d,%[^,],%f,%f",
               utenti[i].username, utenti[i].email,
               &utenti[i].n_anno, utenti[i].tradizione,
               &utenti[i].fasciadiprezzo, &utenti[i].media_voti);

Also, see why is while (!feof(file)) always wrong.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

If my eyes do not deceive me, then utenteis found in different contexts. You can't do that. The compiler, generally speaking, should have thrown an error, бecause it is not clear what it is: the name of the structure type or the name of the local variable? I advise you to use the _t (t means type) postscript for the type names, for example, utente_t.

In addition, if the file contains quotation marks ", then they should also be specified in fscanf using the escape character \ :

fscanf (file, "\"%s,%s,%d,%s,%f,%f\"", ...);
Alexey Ismagilov
  • 187
  • 2
  • 11
  • 1
    Other than being a bad idea, there's nothing technically wrong with having a local variable named `utente` since the `utente` `typedef` occurred in a different scope. The local variable will simply shadow the `typedef`. Also names that end in `_t` are, strictly speaking, reserved by the POSIX standard, so using them isn't necessarily a good idea (although it is a common practice, and not all systems are POSIX). – jamesdlin May 22 '21 at 01:00