Newsgroup: it.comp.os.linux.development
Titolo: programma funziona correttamente in windows, ma non in Linux

Ciao a tutti, sono nuovo della programmazione in C++, ho appena iniziato 
a studiarla (ho iniziato quest'anno col C). Ho scritto un programma per 
calcolare il numero di giorni che trascorrono tra due date dello stesso 
anno, e l'ho inserito all'interno di un oggetto (in una libreria 
separata). Il programma su windows funziona correttamente, mentre su 
Linux (ho provato con due differenti distribuzioni, naturalmente dopo 
aver ricompilato) da risultati completamente sballati. Esempio tra 
26/03/2008 e 12/05/2008 trascorrono 47 giorni windows lo segnala 
correttamente, Linux dice che ne trascorrono -14!!! Qualcuno sa 
spiegarmi il perch�??? Con Windows uso l'ide dev C++, che utilizza gcc e 
g++ come compilatore (lo stesso che uso in ambiente Linux). RIngrazio in 
anticipo chiunque possa aiutarmi.
Questo � il programma:
giorni.cpp
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include"date.h"
#include<iostream>
using namespace std;
main()
{
  system("cls");
  date prova1;
  prova1.acquisisci();
  cin.get();
}
questa la libreria:
date.h
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct data
  {
   int giorno;
   int mese;
   int anno;
  };
  data inizio,fine;
int mesi[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int mesi_annobis[12]={31,29,31,30,31,30,31,31,30,31,30,31};
int bis=0;
char partenza[11]; //dichiaro due stringhe//
char arrivo[11];
int giorni_res=0;  //variabili per contenere ritorno funzioni//
int giorni_tot=0;
class date
{
public:
void acquisisci();
private:
void carica_struttura(char a[],int dimensione,data &b); //passo la 
struttura per riferimento//
int giorni_residui(int mese_partenza,int giorno_mese); //mi calcola i 
giorni che mancano alla fine del mese di partenza//
int giorni_totali(int residui);
int bisestile(int anno);
}; //chiusura classe
//definizioni funzioni public//
void date::acquisisci()
{
  cout<<"\n\nquesto programma calcola il numero di giorni trascorsi tra 
due date";
  cout<<"\n\nil risultato e' corretto solo se l'anno e' lo stesso";
  cout<<"\n\ninserisci data iniziale (formato GG/MM/AAAA): ";
  gets(partenza);
  cout<<"\n\ninserisci data finale (formato GG/MM/AAAA): ";
  gets(arrivo);
  //lettura date//
  system("cls");
  cout<<"\n\nle date che hai inserito sono:";
  cout<<"\n\n";
  puts(partenza);
  cout<<"\n\n";
  puts(arrivo);
  //chiamate funzioni//
  //con queste chiamate passo le date dalle stringhe alle strutture//
  carica_struttura(partenza,10,inizio);
  carica_struttura(arrivo,10,fine);
  bis=bisestile(inizio.anno);
  giorni_res=giorni_residui(inizio.mese,inizio.giorno);
  giorni_tot=giorni_totali(giorni_res);
  giorni_tot=giorni_tot+fine.giorno;
  cout<<"\n\n";
  cout<<"tra le due date sono trascorsi "<<giorni_tot<<" giorni";
};
//definizioni funzioni private//
void date::carica_struttura(char a[],int dimensione,data &b) //passo la 
struttura per riferimento//
{
   //stringhe per separare data//
  char day[3];
  char month[3];
  char year[5];
  int i=0; //indice stringa data//
  int j=0; //indice stringhe separate//
  /*con tre cicli for separo la stringa iniziale in tre parti*/
  for(i=0;i<2;i++)
  {
   day[j]=a[i];
   j++;
  }
  day[j]='\0';
  j=0;
  for(i=3;i<5;i++)
  {
   month[j]=a[i];
   j++;
  }
  month[j]='\0';
  j=0;
  for(i=6;i<11;i++)
  {
    year[j]=a[i];
    j++;
  }
  year[j]='\0';
   /*converto le tre stringhe in numeri*/
  /* e assegno valori stringhe convertite a campi struttura*/
  b.giorno=atoi(day);
  b.mese=atoi(month);
  b.anno=atoi(year);
  return;
};  //chiusura funzione carica strutture//
int date::giorni_residui(int mese_partenza,int giorno_mese) //mi calcola 
i giorni che mancano alla fine del mese di partenza//
{
  int residui;
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    residui=(mesi[mese_partenza-1]-giorno_mese);
   }
   else
   {
    residui=(mesi_annobis[mese_partenza-1]-giorno_mese);
   }
  }
  else
  {
   residui=(mesi[mese_partenza-1]-giorno_mese);
  }
  return residui;
}; //chiusura funzione giorni residui//
int date::bisestile(int anno)
{
  if((anno%4==0)&&(anno%100!=0)||(anno%400==0))
  {return 1;}
  else
  {return 0;}
}; //chiusura funzione anno bisestile//
int date::giorni_totali(int residui)
{
  int i=0;
  int giorni=0;
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
   }
   else
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi_annobis[i];
    }
   }
  }
  else
  {
   for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
  }
  giorni=giorni+residui;
  return giorni;
}; //chiusura funzione giorni totali//

 spiegarmi il perch�???
Non ho tempo per guardare il codice ma al 99.99999% la colpa e' tua:
il codice e' scritto male e su windows funziona per pura fortuna.
Potrei azzardare un'ipotesi: non inizializzi una variabile da qualche
parte e su windows questa variabile "fortunatamente" vale 0 (magari e'
proprio il valore che ti serve), su Linux no. Ma come ho detto e' solo
un'ipotesi, ci potrebbero essere molte altre spiegazioni...
Comunque dal codice si evince che non ti sono molto chiari alcuni
concetti del C++ ed in particolare gli streams (evita gets e puts)
quindi ti consiglio di dare un'occhiata ad un buon manuale perche' il
tuo codice e' molto lontano dall'essere codice C++ accettabile
(praticamente e' piu' C che C++).
L'unica cosa che mi lascia perplesso e' che, come l'hai riportato, il
codice non dovrebbe compilare su Linux, visto che non esiste conio.h.
Saluti,
The Librarian

 The Librarian
La conio.h c'è nella versione per Windows, per Linux invece esiste una 
implementazione libera, che si appoggia sulle librerie ncurses. Ho 
notato un altro problema su un programma scritto in C: è lo stesso 
codice che ho poi utilizzato per l'oggetto nel porgramma in C++. Se 
salvo in programma con estensione cpp compilo senza problemi (comunque 
solita differenza di funzionamento su Linux). Invece se salvo con 
estensione c il compilatore mi restituisce un errore di sintassi nel 
prototipo della funzione (solo se tento il passaggio per riferimento, 
non con quello per valore). Forse non riconosce il tipo che definisco 
con la struct? Ho provato ad usare typedef, ma il risultato non cambia. 
Questo è il codice:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>
  typedef struct /*dichiaro una struttura FUORI dal main, perchè ho una 
funzione*/
  {           /*che deve prendere in ingresso un parametro di tipo 
struttura*/
   int giorno;
   int mese;
   int anno;
  }data; //dichiaro due variabili di tipo struttura//;
  data inizio,fine;
//prototipi funzioni//
  void carica_struttura(char a[],int dimensione,data &b); //passo la 
struttura per riferimento//
  int giorni_residui(int mese_partenza,int giorno_mese); //mi calcola i 
giorni che mancano alla fine del mese di partenza//
  int giorni_totali(int residui);
  int bisestile(int anno);
  //variabili globali//
  /*dichiaro queste variabili fuori dal main, perchè devono essere 
utilizzate da più strutture//
  /*utilizzo due array che contengono il numero di giorni di ogni mese*/
   /*uno per l'anno di 365 giorni, e uno per il bisestile*/
  int mesi[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  int mesi_annobis[12]={31,29,31,30,31,30,31,31,30,31,30,31};
  int bis=0;
main()
{
  char partenza[11]; //dichiaro due stringhe//
  char arrivo[11];
  int giorni_res=0;  //variabili per contenere ritorno funzioni//
  int giorni_tot=0;
  //acquisizione dati//
  printf("\n\nquesto programma calcola il numero di giorni trascorsi tra 
due date");
  printf("\n\nil risultato e' corretto solo se l'anno e' lo stesso");
  printf("\n\ninserisci data iniziale (formato GG/MM/AAAA): ");
  gets(partenza);
  printf("\n\ninserisci data finale (formato GG/MM/AAAA): ");
  gets(arrivo);
  //lettura date//
  system("cls");
  printf("\n\nle date che hai inserito sono:");
  printf("\n\n");
  puts(partenza);
  printf("\n\n");
  puts(arrivo);
  //chiamate funzioni//
  //con queste chiamate passo le date dalle stringhe alle strutture//
  carica_struttura(partenza,11,inizio);
  carica_struttura(arrivo,11,fine);
  bis=bisestile(inizio.anno);
  giorni_res=giorni_residui(inizio.mese,inizio.giorno);
  giorni_tot=giorni_totali(giorni_res);
  giorni_tot=giorni_tot+fine.giorno;
  printf("\n\n");
  printf("tra le due date sono trascorsi %d giorni",giorni_tot);
  getchar();
} //chiusura main//
   //definizione funzioni//
void carica_struttura(char a[],int dimensione,data &b)
{
  //stringhe per separare data//




  j=0;

  j=0;


  b.giorno=atoi(day);
  b.mese=atoi(month);
  b.anno=atoi(year);

int giorni_residui(int mese_partenza,int giorno_mese)
{
  int residui;
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    residui=(mesi[mese_partenza-1]-giorno_mese);
   }
   else
   {
    residui=(mesi_annobis[mese_partenza-1]-giorno_mese);
   }
  }
  else
  {
   residui=(mesi[mese_partenza-1]-giorno_mese);
  }
  return residui;
}; //chiusura funzione giorni residui//
int bisestile(int anno)
{
  if((anno%4==0)&&(anno%100!=0)||(anno%400==0))
  {return 1;}
  else
  {return 0;}
}; //chiusura funzione anno bisestile//
int giorni_totali(int residui)
{
  int i=0;
  int giorni=0;
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
   }
   else
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi_annobis[i];
    }
   }
  }
  else
  {
   for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
  }
  giorni=giorni+residui;
  return giorni;
}; //chiusura funzione giorni totali//
e questi i messaggi di errore:
25 date e giorni.c syntax error before '&' token
84 date e giorni.c syntax error before '&' token
date e giorni.c In function `carica_struttura':
99 date e giorni.c `a' undeclared (first use in this function)
Each undeclared identifier is reported only once  for each function it 
appears in
125 date e giorni.c `b' undeclared (first use in this function)

 riferimento,
Su linux se usi l'estensione .c chiami il compilatore per il C, mentre 
se usi l'estensione .cpp chiami il compilatore per C++.
Anche se formalmente usi il comando gcc vengono usati step di 
compilazione diversi.  Naturalmente, visto il codice che ha postato, 
dovresti usare l'estensione .cpp.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

dragonet ha scritto:

Se salvi il file con estensione .c il compilatore lo vede come codice c 
e quindi i reference non li puoi utilizzare, devi invece utilizzare i 
puntatori. Se utilizzi l'estensione .cpp puoi utilizzare i reference in 
quanto il file viene compilato come sorgente c++. Prova ad utilizzare il 
debug per vedere da dove parte l'errore

thecaesar ha scritto:

Ok, adesso ho corretto il codice utilizzando un puntatore a struttura. 
Non ho più errori di compilazione, ne su windows ne su linux, ma sul 
pinguino il programma continua a darmi risultati sballati! Per esempio 
da oggi al 12/05/2008 trascorrono 43 giorni (secondo windows), linux 12. 
Sembra che non mi faccia l'acquisizione della prima stringa, e di 
conseguenza non carica la prima struttura. Quindi calcola i giorni 
trascorsi in base al giorno della seconda data. Il linguaggio è lo 
stesso, il codice è corretto, il compilatore lo stesso (anche se le 
versioni sono differenti: più recente su linux)e allora cosa non 
funziona?!! Che sia colpa della gets? (visto che il compilatore mi 
segnala che è pericolosa e non andrebbe usata).
Questo è il codice con il puntatore a struttura:
/*questo programma calcola quanti giorni sono trascorsi tra due date 
acquisite con una stringa*/
/*utilizzando una funzione che prende in ingresso una stringa e una 
struttura vuota*/
/*e restituisce la struttura i cui campi sono riempiti con i dati 
estrapolati*/
/*dalla stringa. Funziona solo se le date hanno lo stesso anno*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
  typedef struct /*dichiaro una struttura FUORI dal main, perchè ho una 
funzione*/
  {             /*che deve prendere in ingresso un parametro di tipo 
struttura*/
   int giorno; /*con typedef dichiarato il nome di un tipo*/
   int mese;
   int anno;
  }data;
  data inizio,fine,*p; //dichiaro due variabili di tipo struttura e un 
puntatore a struttura//
//prototipi funzioni//
  void carica_struttura(char a[],int dimensione,data *p); //passo la 
struttura per riferimento//
                                                          //tramite un 
puntatore//
  int giorni_residui(int mese_partenza,int giorno_mese); //mi calcola i 
giorni che mancano alla fine del mese di partenza//
  int giorni_totali(int residui);
  int bisestile(int anno);
  //variabili globali//
  /*dichiaro queste variabili fuori dal main, perchè devono essere 
utilizzate da più strutture//
  /*utilizzo due array che contengono il numero di giorni di ogni mese*/
   /*uno per l'anno di 365 giorni, e uno per il bisestile*/
  int mesi[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  int mesi_annobis[12]={31,29,31,30,31,30,31,31,30,31,30,31};
  int bis=0;
  int mese_coincidente=0;
main()
{
  char partenza[11]; //dichiaro due stringhe//
  char arrivo[11];
  int giorni_res=0;  //variabili per contenere ritorno funzioni//
  int giorni_tot=0;
  //acquisizione dati//
  printf("\n\nquesto programma calcola il numero di giorni trascorsi tra 
due date");
  printf("\n\nil risultato e' corretto solo se l'anno e' lo stesso");
  printf("\n\ninserisci data iniziale (formato GG/MM/AAAA): ");
  gets(partenza);
  printf("\n\ninserisci data finale (formato GG/MM/AAAA): ");
  gets(arrivo);
  //lettura date//
  system("cls");
  printf("\n\nle date che hai inserito sono:");
  printf("\n\n");
  puts(partenza);
  printf("\n\n");
  puts(arrivo);
  //chiamate funzioni//
  //con queste chiamate passo le date dalle stringhe alle strutture//
  carica_struttura(partenza,11,&inizio); //con la & assegno al puntatore 
a struttura l'indirizzo//
  carica_struttura(arrivo,11,&fine);     //delle strutture inizio e fine//
  bis=bisestile(inizio.anno);
  giorni_res=giorni_residui(inizio.mese,inizio.giorno);
  giorni_tot=giorni_totali(giorni_res);
  if(mese_coincidente==0)
  {
   giorni_tot=giorni_tot+fine.giorno;
  }
  else
  {giorni_tot=giorni_tot;}
  printf("\n\n");
  printf("tra le due date sono trascorsi %d giorni",giorni_tot);
  getchar();
} //chiusura main//
   //definizione funzioni//
void carica_struttura(char a[],int dimensione,data *p)
{
  //stringhe per separare data//
  char day[3];
  char month[3];
  char year[5];
  int i=0; //indice stringa data//
  int j=0; //indice stringhe separate//
  /*con tre cicli for separo la stringa iniziale in tre parti*/
  for(i=0;i<2;i++)
  {
   day[j]=a[i];
   j++;
  }
  day[j]='\0';
  j=0;
  for(i=3;i<5;i++)
  {
   month[j]=a[i];
   j++;
  }
  month[j]='\0';
  j=0;
  for(i=6;i<11;i++)
  {
    year[j]=a[i];
    j++;
  }
  year[j]='\0';
   /*converto le tre stringhe in numeri*/
  /* e assegno valori stringhe convertite a campi struttura*/
  p->giorno=atoi(day);  //con l'operatore -> raggiungo tramite puntatore 
i membri della struttura//
  p->mese=atoi(month);
  p->anno=atoi(year);
  return;
};  //chiusura funzione carica strutture//
int giorni_residui(int mese_partenza,int giorno_mese)
{
  int residui;
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    residui=(mesi[mese_partenza-1]-giorno_mese);
   }
   else
   {
    residui=(mesi_annobis[mese_partenza-1]-giorno_mese);
   }
  }
  else
  {
   residui=(mesi[mese_partenza-1]-giorno_mese);
  }
  return residui;
}; //chiusura funzione giorni residui//
int bisestile(int anno)
{
  if((anno%4==0)&&(anno%100!=0)||(anno%400==0))
  {return 1;}
  else
  {return 0;}
}; //chiusura funzione anno bisestile//
int giorni_totali(int residui)
{
  int i=0;
  int giorni=0;
  if(inizio.mese==fine.mese)
  {
   mese_coincidente=1;
   giorni=fine.giorno-inizio.giorno;
   return giorni;
  }
  if(inizio.mese>=2)
  {
   if(bis==0)
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
   }
   else
   {
    for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi_annobis[i];
    }
   }
  }
  else
  {
   for(i=inizio.mese;i<fine.mese-1;i++)
    {
    giorni=giorni+mesi[i];
    }
  }
  giorni=giorni+residui;
  return giorni;
}; //chiusura funzione giorni totali//
Please help me!!!

 conseguenza non carica la prima struttura. Quindi calcola i giorni 
Si chiama "debug", ed e' probabilmente l'aspetto piu` noioso della 
programmazione con cui TUTTI i programmatori hanno a che fare.
Invece di dire:
 > trascorsi in base al giorno della seconda data. Il linguaggio è lo
 > stesso, il codice è corretto, il compilatore lo stesso (anche se le
 > versioni sono differenti: più recente su linux)e allora cosa non
 > funziona?!! Che sia colpa della gets? (visto che il compilatore mi
 > segnala che è pericolosa e non andrebbe usata).
Puoi semplicemente aggiungere dopo la "gets", una printf (o, meglio una 
std::cout visto che scrivi in C++) che stampi a video il parametro preso 
dall'utente, a fare un test del genere ci metti meno che a scrivere un 
messaggio in un newsgroup. Le console di linux e windows sono molto 
diverse quindi non si puo` escludere che il problema stia li`.
Come ti e` gia` stato suggerito ti consiglio anch`io di usare std::cin 
invece di gets, non solo perche` stai scrivendo un programma in C++, ma 
anche perche` cin internamente gestisce meglio le differenti strategie 
di buffering della console su cui si trova.
Inoltre scritto cosi` il tuo programma e` una bomba a orologeria, se uno 
specifica una partenza o un arrivo di 11 caratteri o piu` bomba di 
sicuro il computer.
Usa le stringhe (std::string), non gli array di caratteri.
Bye,
  Gabry

 
[ CUT ]
e aggiungo,
dal punto di vista della progettazione ad oggetti fa un po pietà.
Che senso ha immettere un get dentro un metodo di una classe date
oppure che senso hanno i metodi acquisisci,carica_struttura, ecc..;
sono completamenti fuori dal contesto di una classe date.