Newsgroup: it.comp.lang.c++
Titolo: differenza funzionamento programma da windows a 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//

 Questo è il programma:
Ci sarebbero varie cose da sistemare (se ti interessa se ne può 
discutere). Ma non vedo come possa dare il comportamento che hai 
menzionato. Sospetto però che il codice che hai postato non sia quello 
che hai compilato sotto Linux. Lo header "conio.h" non c'è (che io 
sappia) nelle distribuzioni linux. In realtà penso che non dovrebbe 
esserci neanche in Dev-Cpp...
E.

 esserci neanche in Dev-Cpp...
in dev-cpp la conio.h c'è
bye

 bye
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)

 correttamente, Linux dice che ne trascorrono -14!!! 
Dovresti cercare di restringere all'osso il codice che genera l'errore. 
Fatti stampare dei valori intermedi, e verifica quale parte del codice 
si comporta in maniera insaspettata. Se poi non risolvi almeno puoi 
postare un codice più breve e avrai più probabilità che qualcuno sia 
disposto a leggerlo...
E.

 con la struct?
Il GCC, come altri compilatori, a meno di usare opzioni specifiche, usa 
il compilatore C sui sorgenti con estensione .c e il compilatore C++ sui 
sorgenti con estensione .cpp.
In linguaggio C non esiste il passaggio per riferimento, per cui se 
compili il tuo programma C++ con un compilatore C, tale costrutto viene 
segnalato come errore.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila