Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - [help] errore byte letti fread()
Forum - C/C++ - [help] errore byte letti fread()

Avatar
norbix (Ex-Member)
Newbie


Messaggi: 15
Iscritto: 14/09/2008

Segnala al moderatore
Postato alle 23:35
Domenica, 21/09/2008
la funzione fread non ritorna il numero esatto di byte letti, anche se in effetti il contenuto della stringa in memoria, allocata dinamicamente, è esatto

succede solo con i file da 2-3kB in su

Codice sorgente - presumibilmente C#

  1. char *read_file(char *fname) // ritorna NULL se c'è un errore, altrimenti ritorna i dati letti
  2. {
  3.      FILE *f;
  4.      long size;
  5.      char *data;
  6.  
  7.      size = get_file_size(fname);
  8.  
  9.      if(size == -1) return NULL;
  10.      else if((data = (char *)malloc(size)) == NULL) return NULL;
  11.      data[size] = 0;
  12. long k;
  13.      f = fopen(fname, "r");
  14.      if((k = fread(data, 1, size, f)) != size)
  15.      {
  16.           fclose(f);
  17.           printf("ciao, errore lettura.. letti solo %d byte\n", k);
  18.           //return NULL;
  19.      }
  20.  
  21.      fclose(f);
  22.      return data;
  23. }
  24.  
  25. short write_file(char *fname, char *data) // se fallisce ritorna 0, altrimenti 1
  26. {
  27.      FILE *f;
  28.      long size;
  29.  
  30.      size = strlen(data);
  31.  
  32.      if((f = fopen(fname, "w")) == NULL) return 0;
  33.      else if(fwrite(data, 1, size, f) != size) return 0;
  34.  
  35.      fclose(f);
  36.      return 1;
  37. }



ho postato la funzione write_file() per completezza, questa funzione non da nessun problema

vi chiedo aiuto perchè ho ripreso un vecchio sorgente di un cifrario di vigenere per file di testo, e lo sto ristrutturando, ma con password più lunghe di 2-3 caratteri in combinazione con file della dimensione citata sopra.. si blocca tutto, non capisco il perchè, intanto ricontrollo la funzione per l'ottenimento della password, sperando di trovare qualche errore

resta comunque il fatto che la fread() ritorna un valore di byte letti minore rispetto a quello effettivo, e credo che qualcuno abbia già sperimentato fread() abbastanza a fondo per rispondere

saluti

PM Quote
Avatar
Overflow (Normal User)
Expert


Messaggi: 334
Iscritto: 11/01/2008

Segnala al moderatore
Postato alle 13:57
Lunedì, 22/09/2008
prova a postare il codice della funzione get_file_size() credo che l'errore sia li. Ti rimando a
http://digilander.libero.it/uzappi/C/librerie/funzioni/fre ... per maggiori info sulla fread().

Ultima modifica effettuata da Overflow il 22/09/2008 alle 14:10
PM Quote
Avatar
norbix (Ex-Member)
Newbie


Messaggi: 15
Iscritto: 14/09/2008

Segnala al moderatore
Postato alle 17:32
Lunedì, 22/09/2008
grazie per l'interessamento e per il link

Codice sorgente - presumibilmente C++

  1. // cifrario di vigenere, su file di testo, versione 2, restaurata
  2.  
  3. // author: N0R81X
  4. // MSN:    bobcat01@hotmail.com (no mail)
  5. // eMail:  xibron[at]gmail[dot]com (no spam!)
  6.  
  7. #include <stdio.h>
  8. #include <conio.h>
  9. #include <string.h>
  10. #include <windows.h>
  11. #include <stdlib.h>
  12.  
  13. void anim(char *text);
  14. char rotate_left(char c);
  15. char rotate_right(char c);
  16. char rotate(char c, int n, char direction);
  17. char *vigenere_enc(char *plaintext, char *pass);
  18. char *vigenere_dec(char *ciphertext, char *pass);
  19. char *get_worm(long lenght, char *pass);
  20. long get_file_size(char *fname);
  21. char *read_file(char *fname);
  22. short write_file(char *fname, char *data);
  23. void str_to_upper(char *str);
  24. char *get_password(long max_lenght);
  25. int char_check(char *pass);
  26. int lenght_check(char *pass, long max_lenght);
  27. void clear(void);
  28. void gotoXY(int x, int y);
  29.  
  30. int main()
  31. {
  32.      char *plaintext, *ciphertext;
  33.      char fname[1024], *pass, temp[1024];
  34.      char choice;
  35.      long lenght;
  36.  
  37.      while(1)
  38.      {
  39.           clear();
  40.           anim("\n\n ~ Cifrario di Vigenere v2 by N0R81X ~ \n\n");
  41.           anim("1 - Codifica\n");
  42.           anim("2 - Decodifica\n");
  43.           anim("3 - Esci\n\n");
  44.  
  45.           choice = getch();
  46.  
  47.           if(choice == '1')
  48.           {
  49.                anim("File di testo da cifrare: ");
  50.                fgets(fname, 1024, stdin);
  51.                fname[strlen(fname) - 1] = 0;
  52.  
  53.                if((plaintext = read_file(fname)) == NULL)
  54.                {
  55.                     sprintf(temp, "Impossibile leggere %s\n", fname);
  56.                     anim(temp);
  57.                     getch();
  58.                     return 0;
  59.                }
  60.  
  61.                lenght = get_file_size(fname);
  62.                printf("Lunghezza testo: %d byte\n", lenght);
  63.  
  64.                pass = get_password(lenght);
  65.                if(pass == NULL)
  66.                {
  67.                     anim("Errore nella lettura della password\n");
  68.                     getch();
  69.                     return 0;
  70.                }
  71.  
  72.                ciphertext = (char *)malloc(lenght + 1);
  73.                if(ciphertext == NULL) return 0;
  74.                ciphertext[lenght + 1] = 0;
  75.  
  76.                ciphertext = vigenere_enc(plaintext, pass);
  77.  
  78.                if((write_file(fname, ciphertext)) == 0)
  79.                {
  80.                     sprintf(temp, "Impossibile scrivere %s\n", temp);
  81.                     anim(temp);
  82.                     getch();
  83.                     return 0;      
  84.                }
  85.  
  86.                free(plaintext);
  87.                free(ciphertext);
  88.                anim("File cifrato!\n");
  89.           }
  90.           else if(choice == '2')
  91.           {
  92.                anim("File di testo da decifrare: ");
  93.                fgets(fname, 1024, stdin);
  94.                fname[strlen(fname) - 1] = 0;
  95.  
  96.                if((ciphertext = read_file(fname)) == NULL)
  97.                {
  98.                     sprintf(temp, "Impossibile leggere %s\n", fname);
  99.                     anim(temp);
  100.                     getch();
  101.                     return 0;
  102.                }
  103.  
  104.                lenght = get_file_size(fname);
  105.                printf("Lunghezza testo: %d byte\n", lenght);
  106.  
  107.                pass = get_password(lenght);
  108.  
  109.                plaintext = (char *)malloc(lenght);
  110.                if(plaintext == NULL) return 0;
  111.  
  112.                plaintext = vigenere_dec(ciphertext, pass);
  113.  
  114.                if((write_file(fname, plaintext)) == 0)
  115.                {
  116.                     sprintf(temp, "Impossibile scrivere %s\n", temp);
  117.                     anim(temp);
  118.                     getch();
  119.                     return 0;      
  120.                }
  121.  
  122.                free(plaintext);
  123.                free(ciphertext);
  124.                anim("File decifrato!\n");
  125.           }
  126.           else if(choice == '3') return 0;
  127.           else if(choice < '1' || choice > '2')
  128.           {
  129.                sprintf(temp, "Scelta 1, 2 o 3, nessuna scelta %c!\n", choice);
  130.                anim(temp);
  131.           }
  132.  
  133.           getch();
  134.      }
  135. }
  136.  
  137. void anim(char *text)
  138. {
  139.      int i;
  140.  
  141.      for(i = 0; i <= strlen(text); i++)
  142.      {
  143.           printf("%c", text[i]);        
  144.           if((text[i] != ' ') || (text[i] != '\n')) _sleep(15);
  145.      }
  146. }
  147.  
  148. char rotate_left(char c)
  149. {
  150.      if(c >= 'A' && c <= 'Z')
  151.      {
  152.           if(c == 'A') c = 'Z';
  153.           else c--;
  154.      }
  155.      else if(c >= 'a' && c <= 'z')
  156.      {
  157.           if(c == 'a') c = 'z';
  158.           else c--;
  159.      }
  160.      else if(c >= '0' && c <= '9')
  161.      {
  162.           if(c == '0') c = '9';
  163.           else c--;
  164.      }
  165.  
  166.      return c;
  167. }
  168.  
  169. char rotate_right(char c)
  170. {
  171.      if(c >= 'A' && c <= 'Z')
  172.      {
  173.           if(c == 'Z') c = 'A';
  174.           else c++;
  175.      }
  176.      if(c >= 'a' && c <= 'z')
  177.      {
  178.           if(c == 'z') c = 'a';
  179.           else c++;
  180.      }
  181.      else if(c >= '0' && c <= '9')
  182.      {
  183.           if(c == '9') c = '0';
  184.           else c++;
  185.      }
  186.  
  187.      return c;
  188. }
  189.  
  190. char rotate(char c, int n, char direction)
  191. {
  192.      int i;
  193.  
  194.      if(direction == 'L')
  195.      {
  196.           for(i = 0; i < n; i++) c = rotate_left(c);
  197.      }
  198.      else if(direction == 'R')
  199.      {
  200.           for(i = 0; i < n; i++) c = rotate_right(c);
  201.      }
  202.  
  203.      return c;
  204. }
  205.  
  206. char *vigenere_enc(char *plaintext, char *pass) // la password deve essere passata alla funzione in caratteri maiuscoli
  207. {
  208.      long i, lenght = strlen(plaintext);
  209.      char *worm = get_worm(lenght, pass);
  210.      char *ciphertext = (char *)malloc(lenght);
  211.  
  212.      if(ciphertext == NULL) return NULL;
  213.  
  214.      for(i = 0; i <= lenght; i++)
  215.      {
  216.           ciphertext[i] = rotate(plaintext[i], worm[i] - 'A', 'R');
  217.      }
  218.  
  219.      return ciphertext;
  220. }
  221.  
  222. char *vigenere_dec(char *ciphertext, char *pass) // la password deve essere passata alla funzione in caratteri maiuscoli
  223. {
  224.      long i, lenght = strlen(ciphertext);
  225.      char *worm = get_worm(lenght, pass);
  226.      char *plaintext = (char *)malloc(lenght+1);
  227.  
  228.      if(plaintext == NULL) return NULL;
  229.  
  230.      for(i = 0; i <= lenght; i++)
  231.      {
  232.           plaintext[i] = rotate(ciphertext[i], worm[i] - 'A', 'L');
  233.      }
  234.  
  235.      return plaintext;
  236. }
  237.  
  238. char *get_worm(long lenght, char *pass)
  239. {
  240.      char *worm;
  241.      long i;
  242.      int pass_len = strlen(pass);
  243.  
  244.      if((worm = (char *)malloc(lenght)) == NULL) return NULL;
  245.      memset(worm, 0, lenght);
  246.  
  247.      for(i = 0; i < lenght / pass_len; i++)
  248.      {
  249.           strcat(worm, pass);
  250.      }
  251.      for(i = 0; i < lenght % pass_len; i++)
  252.      {
  253.           strncat(worm, pass, lenght % pass_len);
  254.      }
  255.  
  256.      return worm;
  257. }
  258.  
  259. long get_file_size(char *fname) // ritorna -1 se è impossibile aprire il file
  260. {
  261.      FILE *f;
  262.      long size;
  263.  
  264.      if((f = fopen(fname, "r")) == NULL) return -1;
  265.  
  266.      fseek(f, 0, SEEK_END);
  267.      size = ftell(f);
  268.      fclose(f);
  269.      return size;
  270. }
  271.  
  272. char *read_file(char *fname) // ritorna NULL se c'è un errore, altrimenti ritorna i dati letti
  273. {
  274.      FILE *f;
  275.      long size;
  276.      char *data;
  277.  
  278.      size = get_file_size(fname);
  279.  
  280.      if(size == -1) return NULL;
  281.      else if((data = (char *)malloc(size)) == NULL) return NULL;
  282.      data[size] = 0;
  283. long k;
  284.      f = fopen(fname, "r");
  285.      if((k = fread(data, 1, size, f)) != size)
  286.      {
  287.           fclose(f);
  288.           printf("ciao, errore lettura.. letti solo %d byte\n", k);
  289.           //return NULL;
  290.      }
  291.  
  292.      fclose(f);
  293.      return data;
  294. }
  295.  
  296. /*char *read_file(char *fname) // ritorna NULL se c'è un errore, altrimenti ritorna i dati letti
  297. {
  298.      FILE *f;
  299.      long size, i;
  300.      char *data;
  301.  
  302.      size = get_file_size(fname);
  303.  
  304.      if(size == -1) return NULL;
  305.      else if((data = (char *)malloc(size)) == NULL) return NULL;
  306.      memset(data, 0, size);
  307.  
  308.      f = fopen(fname, "r");
  309.  
  310.      for(i = 0; i <= size; i++) data[i] = getc(f);
  311.  
  312.      fclose(f);
  313.      return data;
  314. }*/
  315.  
  316. short write_file(char *fname, char *data) // se fallisce ritorna 0, altrimenti 1
  317. {
  318.      FILE *f;
  319.      long size;
  320.  
  321.      size = strlen(data);
  322.  
  323.      if((f = fopen(fname, "w")) == NULL) return 0;
  324.      else if(fwrite(data, 1, size, f) != size) return 0;
  325.  
  326.      fclose(f);
  327.      return 1;
  328. }
  329.  
  330. void str_to_upper(char *str)
  331. {
  332.      int i;
  333.  
  334.      for(i = 0; i <= strlen(str); i++)
  335.      {
  336.           if(str[i] >= 'a' && str[i] <= 'z') str[i] = str[i] - 32;
  337.      }
  338. }
  339.  
  340. char *get_password(long max_lenght)
  341. {
  342.      char *pass = (char *)malloc(1024);
  343.      if(pass == NULL) return NULL;
  344.  
  345.      while(1)
  346.      {
  347.           anim("Password (case insensitive): ");
  348.           fgets(pass, 1024, stdin);
  349.           pass[strlen(pass) - 1] = 0;
  350.  
  351.           str_to_upper(pass);
  352.  
  353.           if(char_check(pass) && lenght_check(pass, max_lenght))
  354.           {
  355.                break;
  356.           }
  357.      }
  358.  
  359.      return pass;
  360. }
  361.  
  362. int char_check(char *pass) // controlla che nella password non ci siano numeri
  363. {
  364.      int i, j, flag;
  365.      char allowed_chars[1024] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  366.  
  367.      for(i = 0; i <= strlen(pass); i++)
  368.      {
  369.           flag = 0;
  370.  
  371.           for(j = 0; j <= strlen(allowed_chars); j++)
  372.           {
  373.                if(pass[i] == allowed_chars[j]) flag = 1;          
  374.           }
  375.  
  376.           if(flag != 1)
  377.           {
  378.                anim("La password deve contenere solamente lettere, ed e' case insensitive!\n\n");
  379.                return 0;
  380.           }
  381.      }
  382.  
  383.      return 1;
  384. }
  385.  
  386. int lenght_check(char *pass, long max_lenght) // controlla che la lunghezza della password non superi quella del testo
  387. {
  388.      if(strlen(pass) > max_lenght)
  389.      {
  390.           anim("La password non puo' essere piu' lunga del testo da cifrare!\n\n");
  391.           return 0;
  392.      }
  393.      else return 1;
  394. }
  395.  
  396. void clear(void)
  397. {
  398.      int x, y;
  399.      char *row;
  400.      CONSOLE_SCREEN_BUFFER_INFO c_info;
  401.      HANDLE h_stdout;
  402.  
  403.      h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
  404.      GetConsoleScreenBufferInfo(h_stdout, &c_info);
  405.  
  406.      // printf("Screen size: %dx%d\n", c_info.dwSize.X, c_info.dwSize.Y);
  407.      // printf("Screen size MAX: %dx%d\n", c_info.dwMaximumWindowSize.X, c_info.dwMaximumWindowSize.Y);
  408.      // printf("Cursor position: %d, %d\n", c_info.dwCursorPosition.X, c_info.dwCursorPosition.Y);
  409.      // printf("Boh: left: %d, right: %d, top: %d, bottom: %d\n", c_info.srWindow.Left, c_info.srWindow.Right, c_info.srWindow.Top, c_info.srWindow.Bottom);
  410.  
  411.      // getchar();
  412.  
  413.      // posiziono il cursore sull'angolo nord ovest della console
  414.      gotoXY(0, 0);
  415.      // alloco uno spazio equivalente al prodotto di righe e colonne della console
  416.      row = (char *)malloc((c_info.srWindow.Right + 1) * (c_info.srWindow.Bottom + 1));
  417.      // riempio la stringa ottenuta con spazi bianchi
  418.      memset(row, ' ', (c_info.srWindow.Right + 1) * (c_info.srWindow.Bottom + 1));
  419.      // pulisco lo schermo inserendo spazi bianchi dappertutto
  420.      puts(row);
  421.      // libero la memoria precedentemente allocata
  422.      free(row);
  423.      // riposiziono il cursore sull'angolo nord ovest della console
  424.      gotoXY(0, 0);
  425. }
  426.  
  427. void gotoXY(int x, int y)
  428. {
  429.      HANDLE h_stdout;
  430.      COORD coord;
  431.  
  432.      coord.X = x;
  433.      coord.Y = y;
  434.  
  435.      h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
  436.      SetConsoleCursorPosition(h_stdout, coord);
  437. }


PM Quote
Avatar
Overflow (Normal User)
Expert


Messaggi: 334
Iscritto: 11/01/2008

Segnala al moderatore
Postato alle 18:28
Lunedì, 22/09/2008
ok, la funzione ftell() ritorna un carattere in più(credo sia il carattere di fine stringa) quindi dalla funzione get_file_size() devi fare ritornare size-1.

PM Quote
Avatar
norbix (Ex-Member)
Newbie


Messaggi: 15
Iscritto: 14/09/2008

Segnala al moderatore
Postato alle 21:39
Lunedì, 22/09/2008
ops! grazie.. questa non la sapevo
in effetti avevo risolto mettendo da me il carattere di fine stringa su quanto letto
Codice sorgente - presumibilmente Plain Text

  1. data[size] = 0;

il problema, comunque, persiste

mi correggo, non bisogna ritornare ftell() - 1, poichè leggendo un file contenente solamente "ciao" il valore ritornato è 3, mentre dovrebbe essere 4, come nel caso in cui si ritorni ftell()

Ultima modifica effettuata da norbix il 22/09/2008 alle 21:45
PM Quote