Προς το περιεχόμενο

ANSI C : grafontas se ena arxeio keimenou


Stilewag

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα,

Το πρόγραμμά σου έχει κάποια λάθη, σε γενικές γραμμές τα εξής:

Η fscanf που χρησιμοποιείς πρέπει στο τρίτο όρισμα της να έχει το &Line1[...], δηλαδή διεύθυνση. Το τελευταίο στοιχείο του πίνακα είναι το Line1[94] μιάς και η αρίθμηση αρχίζει από το 0. Μάλιστα, ακόμα και με αυτή τη διόρθωση το πρόγραμμα διαβάζει πέρα από το τέλος του αρχείου. Επίσης, όλοι οι χαρακτήρες αποθηκεύονται σε μία συγκεκριμένη θέση και όχι σε διαδοχικές του πίνακα Line1. Έπειτα, πιθανώς εκτυπώνεται ο "χαρακτήρας" EOF που δεν ειναι εκτυπώσιμος.

 

Για να συνηθίσεις σε πιο καθαρές λύσεις σου παραθέτω ένα πρόγραμμα που διαβάζει από το αρχείο με τον τρόπο που πρότεινε πιο πάνω ο DirectX. Το πρόγραμμα αποθηκεύει την πρώτη γραμμή στον πίνακα Line1 τη δεύτερη στο Line2 και μετά τις τυπώνει. Δεν κατάλαβα αν αυτό ακριβώς ήθελες να κάνεις.

 

 

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


void main(void)
{
  int i=0;
  char c;
  char Line1[95], Line2[95];

  FILE *Cfg = fopen("./config.txt", "rb");

  if (Cfg==NULL)
  {
     printf("Cannot open file config.txt\n");
     return;
  }

  while ((c=fgetc(Cfg))!=EOF && i<95)
  {
     Line1[i]=c;
     i++;
  }

  i=0;
  while((c=fgetc(Cfg))!=EOF && i<95)
  {
     Line2[i]=c;
     i++;
  }

  
  for (i=0;i<95;i++)
     printf("Line1[%d]:%c ",i,Line1[i]);
  printf("\n");
  for (i=0;i<95;i++)
     printf("Line2[%d]:%c ",i,Line2[i]);

}

Δημοσ.

meletaw to komati kwdika pou egrapse o Directx, kai einai kapoia pragmata gia ta opoia den eimai sigouros:

 

>#include <stdio.h>

int   nCharacter, nAlphas = 0;
long  lFileLen =  0;
FILE  *InStream, *OutStream;

void main(void)
{

//to fopen("in.txt","rb"), o compiler to eklamvanei san mia timi pleon?
//gia afto to "sigkrinei" me to NULL
if((InStream=fopen("in.txt","rb"))==NULL)
{
	printf(" Cannot open in.txt for read!\n");
	return;
	//dokimasa na aferesw to return kai apla to programma sinexeise, pws
	//stamataei to programma? pws prepei na to fantastw
}

if((OutStream=fopen("out.txt","wb"))==NULL)
{
	//giati einai aparetito na kleisei to arxeio?
	fclose(InStream);
	printf(" Cannot create out.txt!\n");
	return;
}

//o nCharacter den einai int? pws diavazei enan xaraktira (char)?
//kserw oti mporeis na kaneis ena " myCharacter++ " se mia metavliti
//typou char, alla ginetai to antistrofo?
//alaksa to nCharacter se char, kai to programma doulepse akrivws
//me ton idio tropo (oute kan warning)...
while((nCharacter=fgetc(InStream))!=EOF)
{
	lFileLen++;
	fputc(nCharacter,OutStream);
	if(nCharacter=='a'){ nAlphas++; }
}

fclose(InStream);
fclose(OutStream);

printf(" File  length: %ld\n",lFileLen);
printf(" Alpha count : %d\n",nAlphas);
}

Δημοσ.

Καλησπέρα και πάλι, κοίτα τις επεξηγήσεις παρακάτω:

 

>
#include <stdio.h>

int   nCharacter, nAlphas = 0;
long  lFileLen =  0;
FILE  *InStream, *OutStream;

void main(void)
{

  //to fopen("in.txt","rb"), o compiler to eklamvanei san mia timi pleon?
  //gia afto to "sigkrinei" me to NULL
  //Η fopen() epistrefei ena deikth sto file pou anoikse h NULL an apetyxe  
  //Ayth h timh apo8hkeyetai sto InStream 
 //kai epeita sygrinetai me to NULL
  if((InStream=fopen("in.txt","rb"))==NULL)
  {
     printf(" Cannot open in.txt for read!\n");
     return;
     //dokimasa na aferesw to return kai apla to programma sinexeise, pws
     //stamataei to programma? pws prepei na to fantastw
    //To return prokalei thn epistrofh ths main, ayto theloume na ginei
   //epeidh de mporesame na anoiksoume to arxeio "in.txt"
  }

  if((OutStream=fopen("out.txt","wb"))==NULL)
  {
     //giati einai aparetito na kleisei to arxeio?
     //Dioti exei anoiksei pio panw
     //Genika prepei na kleineis osa arxeia exeis anoiksei
     fclose(InStream);
     printf(" Cannot create out.txt!\n");
     return;
  }
  
  //o nCharacter den einai int? pws diavazei enan xaraktira (char)?
  //kserw oti mporeis na kaneis ena " myCharacter++ " se mia metavliti
  //typou char, alla ginetai to antistrofo?
  //alaksa to nCharacter se char, kai to programma doulepse akrivws
  //me ton idio tropo (oute kan warning)...

  //O nCharacter 8a eprepe na einai tupou char
 //Vevaia kai int pou einai den uparxei kapoio provlhma
 //Mporeis na kaneis nCharacter++ kai se char kai se int
 //Na exeis upopsh sou oti genika ginetai aytomata anagwgh typwn
 //diladi casting xwris warnings.
  while((nCharacter=fgetc(InStream))!=EOF)
  {
     lFileLen++;
     fputc(nCharacter,OutStream);
     if(nCharacter=='a'){ nAlphas++; }
  }
  
  fclose(InStream);
  fclose(OutStream);
  
  printf(" File  length: %ld\n",lFileLen);
  printf(" Alpha count : %d\n",nAlphas);
}

Δημοσ.

Σωστές οι παρατηρήσεις του Sta, η nCharacter λογικά θα μπορούσε να ορισθεί ως unsigned char δηλαδή ως μεταβλητή τιμών μεταξύ 0 ως 255 όμως κάτι τέτοιο στην περίπτωση του παραπάνω κώδικα δεν μπορεί να εφαρμοσθεί καθώς το EOF ισούται με -1 όταν η unsigned char δεν δέχεται αρνητικές τιμές!

 

Όσον αφορά την char για δήλωση αριθμητικών τιμών του ASCII σετ δεν την συνιστώ σε καμία περίπτωση καθώς το εύρος τιμών της είναι πολύ μικρό δηλαδή -128 ως 127 (αυτό που λέμε και ως 7bit BASIC ASCII SET) οπότε αν συναντήσει πχ. τον ASCII χαρακτήρα 250 θα γίνει Overflow με αποτέλεσμα (λόγο carry set) να γυρίσει σε Underflow (-2), τώρα αν δουλεύεις σε 32bit περιβάλλον εργασίας αυτό μπορεί να περάσει απαρατήρητο αρχικά διότι λόγο της εσωτερικής αρχιτεκτονικής του (καθώς όλοι οι τύποι είναι 32bit εσωτερικά) η τιμή γυρίζει σε 0xFFFFFFFA με το FA(=250) να γράφεται σωστά μεν αλλά ειδικά σε 16bit προγραμματισμό αυτό θα μπορούσε να ήταν μεγάλος πονοκέφαλος καθώς κατέστρεφες το stack σου. Ύστερα μην ξεχνάς ότι ο έλεγχος «!=EOF» (όπου EOF = -1) παύει να ισχύει σωστά λόγο των λανθασμένων τιμών (Overflow) με αποτέλεσμα την εγγραφή ως extra byte του ίδιου του EOF (!) ως 0xFF (255) στο αρχείο εξόδου πράγμα που δεν θα έπρεπε σε καμία περίπτωση να συμβεί…

 

Υ.Γ.

Αυτά σε περιβάλλον Windows και Borland C/C++ Builder, δεν έχω πρόχειρη την παλιά Turbo C/C++ μου για DOS ώστε να δω το συγκεκριμένο bug σε τι θα αντίδραση θα οδηγούσε ένα 16μπιτο πρόγραμμα..

Δημοσ.

Ok... twra xathika. Nomiza pws tha tin glitwna, alla den tin glitwnw... :|

 

Paw na agorasw ena vivlio C/C++ :)

 

Einai kalytera na kanw compile ta programmata mou me tin palia Turbo C gia na vlepw lathi pou den tha evlepa ston Builder Compiler?

 

Y.G.: i Turbo C einai pleon freeware :) mporeis na tin katevaseis apo http://bdn.borland.com/museum/ :)

Δημοσ.

Πολύ εύστοχο το σχόλιο του φίλου Directx. Πάντως αν μιλάμε για το βασικό ASCII (7-bits) και με ορισμό char πιστεύω πως δεν υπάρχει πρόβλημα. Η σύγκριση με το EOF (-1) γίνεται κανονικά.

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...