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

ANSI C : grafontas se ena arxeio keimenou


Stilewag

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

Δημοσ.

Eimai protaris stin ANSI C kai psaxnw mia grigori lisi se ena provlima:

 

thelw na grapsw mia leksi (i mia frasi) se ena arxeio ASCII text (.txt). An kapoios exei tin diathesi, as mou dosei ton kwdika gia afto. Katalavainw oti fenetai kapws kouto, alla tha me voithouse poli kai tha mou edine tin othisi na proxwrisw sto na metafrasw ta programata mou apo Pascall se C (kryptografia vasika).

 

Thymamai pws stin Pascal eprepe na kaneis to arxeio close(writeFile); gia na grapsei kai afta pou iparxoun sto buffer, opote an exei kati paromoio kai i C, parakalw simperilavete to.

 

Fysika o kwdikas tha prepei na pliris, diladi na ginetai compile dixws lathi (alliws den tha to katalavw) :)

 

P.S. 1: ean exete kai kapoio tip gia faster code i kai gia MMX utilization (oti mporei na voithisei gia na ginei pio grigoro to programa), peste to :)

 

P.S. 2: o Borland Compiler 5.5 Free einai kalos gia na grafw console applications? Skeftomai ta xrimata pou xreiazontai gia na agorasw tin MS Visual C++, kai isws na min einai aparetito na to apoktisw apo twra. Exw akousei kai to Dev-C...

Δημοσ.

// w = write, προσοχή σβήνει το αρχείο αν υπάρχει!!

FILE *filepointer = fopen("./test.txt", "w");

 

//τυπώνει το κείμενο και αλλάζει γραμμή

fprintf(filepointer, "%s\n", "Hello there!");

 

// τυπώνει κείμενο στη θέση %s και εναν ακέραιο στη θέση %d

fprintf(filepointer, "A string %s and an integer %d", "(boo)", 10);

 

fclose(filepointer);

---

Βασικά μόνο αυτό τον κώδικα χρειάζεσαι (εννοείται πέρα από τον βασικό). Αν πρέπει να διαβάσεις ένα αρχείο χαρακτήρα προς χαρακτήρα μέχρι το τέλος του, ο κώδικας είναι κάπως έτσι:

 

#include <stdio.h>

#include <stdlib.h>

 

int main () {

 

FILE *filepointer = fopen("./test.txt", "r);

 

char tmp;

 

while (!feof(filepointer)) {

// το & μπροστά από το tmp χρειάζεται γιατί η fscanf πρέπει να γνωρίζει τη διεύθυνση της μεταβλητής στην οποία θα αποθηκεύσει το χαρακτήρα

fscanf(filepointer, "%c", &tmp);

// εμφάνιση του χαρακτήρα

printf("%c", tmp);

}

 

fclose(filepointer);

}

 

Νομίζω ο παραπάνω κώδικας έχει ένα λαθάκι με το while (μπορεί να σου εμφανίζει τον τελευταίο χαρακτήρα του αρχείου 2 φορές). Αν το κάνει αυτό, άλλαξε το fscanf με

 

if (fscanf(filepointer, "%c", &tmp) >= 0)

 

και νομίζω θα δουλέψει (αν όχι, δικαιολογούμαι γιατί είμαι με 3 ώρες ύπνου :shock: )

 

Αν χρειάζεσαι να τυπώνεις στο τέλος αρχείου χωρίς να διαγράφεις το περιεχόμενο του, η εντολή είναι η fopen("test.txt", "a"). Αν πρέπει να τυπώνεις σε διάφορα σημεία και όχι σειριακά, τα πράγματα αλλάζουν..

Δημοσ.

Exw ena mikri provlima me ton kwdika :|

 

Egrapsa to akoloutho:

 

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

void main(void)
{
char Ch

FILE *myfile = fopen("./test.txt", "r");

myfile = fopen("./test.txt", "r");

while (!feof(myfile))
{ 
	fscanf(myfile, "%c", &Ch);
	printf("%c", Ch);
}

fclose(myfile);
}

 

kai mou evgale to minima:

 

Declaration syntax error in function main, mou to egrapse gia tin grammi:

 

FILE *myfile = fopen("./test.txt", "r");

 

Ti na alaksw gia na doulepsei?

Δημοσ.

to 90% twn compile-time errors (isws kai parapanw) ofeilodai epeidi xehname na valoume ena ";"

 

edw eheis xehasei na valeis to ";" sto "char Ch" ..

 

epeisis epeiheireis na anoixeis to arheio 2 fores..

ara to programma sou prepei na ginei etsi :

 

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

void main(void) 
{ 
  char Ch;

  FILE *myfile = fopen("./test.txt", "r"); 

  while (!feof(myfile)) 
  { 
     fscanf(myfile, "%c", &Ch); 
     printf("%c", Ch); 
  } 

  fclose(myfile); 
} 

Δημοσ.

Efxaristw :) To programa doulevei mia xara.

 

Prospathisa na proxwrisw parakatw, alla kolisa :(

 

To akoloutho programa exei skopo:

 

1. na diavasei enan-enan tous xaraktires apo to in.txt kai na tous grapsei sto out.txt (kati pou ginetai mia xara)

2. na metrisei to megethos tou in.txt (kai kata sinepeia tou out.txt)

3. na metrisei posa "a" iparxoun mesa sto in.txt kai na mas pei to plithos tous

 

Parousiazei omws merika provlimata:

 

1. mou vgazei to megethos arxeio kata 1 byte megalitero

2. otan vgazw tin grami count1 = 0, tote mou ektipwnei 256 anti gia 0. Mipws kata tin dilwsi mias metavlitis typou int, afti pernei tin timi 256? ...kati paromoio simvainei kai otan vgazw tin grammi fileSize = 0

 

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

void main(void)
{
char Ch;
int count1;
int fileSize;

FILE *inF = fopen("./in.txt", "r");
FILE *outF = fopen("./out.txt", "w");

count1 = 0;
fileSize = 0;

while (!feof(inF))
{
	fileSize++;
	
	if (fscanf(inF, "%c", &Ch) >= 0) 
	fprintf(outF, "%c", Ch);
			
	if (Ch == "a")
	{
		count1++;
		//printf("\nfound an 'a'");
	}
}

printf("filesize: %d", fileSize);
printf("\nnumber of 'a' inside file: %d", count1);

fclose(inF);
fclose(outF);
}

 

Pou exw kanei lathos/lathi? Ef'oson o compiler den vgazei lathi, tote to sfalma einai logikis...

Δημοσ.

Ειλικρινά δεν έχω κοιμηθεί καθόλου καλά από χθες και πάει να σπάσει το κεφάλι μου (!), οπότε αντί να τσεκάρω τον κώδικα σου, έγραψα ένα καινούργιο που πρέπει να δουλεύει καλά.

 

>
#include <stdio.h>

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

void main(void)
{
 if((InStream=fopen("in.txt","rb"))==NULL)
  {
    printf(" Cannot open in.txt for read!\n");
    return;
  }
 if((OutStream=fopen("out.txt","wb"))==NULL)
  {
    fclose(InStream);
    printf(" Cannot create out.txt!\n");
    return;
  }

 while((nCharacter=fgetc(InStream))!=EOF)
  {
    lFileLen++;
    fputc(nCharacter,OutStream);
    if(nCharacter=='a'){ nAlphas++; }
  }

 fclose(InStream);
 fclose(OutStream);

 /* dokimase kai to fcloseall(); an to ypostirizei o compiler sou anti gia duo
    akomja fclose(..)
 */

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

 

Αντί της fscanf (είναι κομματάκι ασυνήθιστη η χρήση της για αυτό –αλλά ότι σε βολεύει) σε συμφέρει να δουλέψεις με την fgetc & fputc που διαχειρίζονται απευθείας bytes, το αρχείο το ανοίγω για ανάγνωση σε κατάσταση binary read (“rb”) και το ίδιο κάνω για το γράψιμο binary write (“wb”), τσεκάρω για τον χαρακτήρα a ως ==‘a’ ζητώντας από τον compiler απευθείας μετατροπή του σε ASCII τιμή.

 

Αν τα δυο τελευταία fclose σε χαλάνε δοκίμασε μια fcloseall(); μερικοί compiler την διαθέτουνε ακόμα και αν δεν το λένε στα documentations τους κάποιοι άλλοι όχι.

 

Το παράδειγμα γράφτηκε σε Borland C/C++ Compiler 5.6.4.

 

Το check in.txt που έφτιαξα είναι

 

>
one airplane
two airplanes
three airplanes
four airplanes
five airplanes

 

Καλή τύχη!!

Δημοσ.

Καλησπέρα και από εμένα,

Εναλλακτικά τροποιώντας ελαφρώς τον κώδικά σου έχουμε το εξής:

#include <stdio.h>

#include <stdlib.h>

 

void main(void)

{

char Ch;

int count1;

int fileSize;

 

FILE *inF = fopen("./in.txt", "rb");

FILE *outF = fopen("./out.txt", "wb");

 

count1 = 0;

fileSize = 0;

 

while (!feof(inF))

{

 

 

if (fscanf(inF, "%c", &Ch) >= 0)

{

fprintf(outF, "%c", Ch);

fileSize++;

}

 

if (Ch =='a')

{

count1++;

/*printf("\nfound an 'a'");*/

}

}

 

printf("filesize: %d", fileSize);

printf("\nnumber of 'a' inside file: %d", count1);

 

fclose(inF);

fclose(outF);

}

 

Παρατήρησε τις αλλαγές και μη διστάσεις να ρωτήσεις γιατί έγιναν αν δεν καταλαβαίνεις κάποια.

Δημοσ.
Efxaristw :)

 

Tha mou parei kapoio kairo gia na katalavw to paradeigma. To diksolo einai na fantastw tin logiki pou leitourgei to WHILE tis ipothesis. Alla pou tha paei :)

>
while((nCharacter=fgetc(InStream))!=EOF)

 

Λέμε while (δλδ για όσο) η μεταβλητή nCharacter που ισούται με ένα byte από το fgetc(InStream) != (δεν είναι ίσα) με EOF, δηλαδή με μια σταθερά της C που προσδιορίζει το τέλος του αρχείου (End Of File), εκτέλεσε τον κώδικα που υπάρχει μέσα στα άγκιστρα που ακολουθούν { }.

 

Εδώ κάνουμε ένα πολύ γνωστό «κόλπο» στην C/C++ όπου την στιγμή που ορίζουμε την τιμή μιας μεταβλητής την ίδια στιγμή ελέγχουμε και την τιμή της οπότε γλιτώνουμε διάφορους μπελάδες (εάν νιώθεις λιγότερο μπερδεμένος από το υπόδειγμα του Sta χρησιμοποίησε το, το δικό μου το έγραψα έτσι ώστε να συνηθίζεις σιγά, σιγά σε πιο τυποποιημένες μορφές σύνταξης C που θα συναντήσεις στο μέλλον).

 

:)

Δημοσ.

Efxristw Directx kai Sta :)

 

Prepei na meletisw kai na "paiksw" ligo me ton kwdika gia ton katalavw teleiws. Oso paei peithomai perisotero oti i C einai i kaliteri glwsa (evelikti, sinoptiki, safis). Mallon eprepe kat'eftheian na arxisw me C anti gia Pascal. Arxizw na aporw, giati oloi lene pws i C einai diskoli.

 

Mallon to lathos mou itan pou evala:

>
if (Ch=="a")

 

enw eprepe na eixa valei:

>
if (Ch=='a')

 

Nomiza oti epeidi stin C vazoume printf("hello"); anti tou writeln('hello');, oti tha einai to idio kai me to comparison if (Ch="a") :roll:

Δημοσ.

Ένα λάθος σου ήταν αυτό, για το οποίο ο compiler πρέπει να σε προειδοποίησε με ένα warning (Κοίτα τα και αυτά γενικώς). Επίσης, ως προς το δικό σου πρόγραμμα (το τροποποιημένο) παρατήρησε τα εξής:

1) Και τα δύο αρχεία ανοίγουν σε binary mode.

2) Κοίτα επίσης το σημείο που γίνεται η αύξηση του fileSize, έτσι ώστε να αποφευχθεί να μετρήσουμε στα bytes του αρχείου το EOF.

3) Το σχόλιο με "//" το τροποποίησα γιατί δεν ξέρω κατά πόσο είναι ANSI C. Προτίμησε τα σχόλια με /*comment*/

 

Βέβαια καλύτερα θα ήταν να κοιτάξεις τον κώδικα του DirextX για να μάθεις να γράφεις πιο σωστά και τυποποιημένα.

Δημοσ.

Nai. Dokimasa kai vgalw to binary mode, alla pali doulepse, kai den mou evgale oute warning.

 

Nai, to fileSize to eida. Telika gi'afto itane kata 1 byte parapanw.

 

Exeis dikaio, to "//" einai tis C++, alla epeidei o compiler to upostirizei kai epeidei to exw sinitheisei apo to quake3/counterstrike scripting, to vazw etsi :) To "/*" einai mallon pio swsto, kai stin CSS etsi prepei na einai ta sxolia alliws mou vgazei lathos.

 

Gia tin wra exw na meletisw pola. Af'otou katalavw plirws pws doulevoun, prepei na dw pws tha to kanw na diavazei ena arxeio rithmisewn, kai meta mia mikroula scripting engine gia poliplokes kriptografiseis gia unattented katastaseis. Alla exw akoma pola psomia mexri ekei, kai me tin empeiria apo tin Pascal, tha mou parei ligotero xrono ap'oti tin prwti fora :)

 

Efxaristw kai pali, dixws tin voitheia sas, den tha evgaza akri.

 

PS: o Borland Compiler 5.5 free, einai kalos?

Δημοσ.

Μια τελευταία επισήμανση: Νομίζω πως τα αρχεία πρέπει να τα ανοίξεις σε binary mode για να κάνεις σωστή καταμέτρηση των bytes που καταλαμβάνουν. Λογικά, θα έτρεξες το παράδειγμα με αρχείο που είναι μόνο μία γραμμή για αυτό και σου έβγαλε σωστό αποτέλεσμα. Διόρθωσε με αν έχω λάθος, πάντως στη δική μου περίπτωση αυτό γίνεται, γενικά είναι και εξαρτώμενο από το λειτουργικό σύστημα.

Δημοσ.

Afto pou thelw na petixw me to akoloutho programa einai na diavasei to arxeio config.txt to opoio exei 2 grammes me ASCII xaraktires (95 xaraktires, oloi oi xaraktires tou pliktrologiou). Einai i stoixeiodis kriptografisi pou alazei enan xaraktira me enan allo. To arxeio rithmisewn tha me glitwsei apo to na grapsw poli kwdika gia na ginoun oi sigkriseis.

 

Prin na ilopoiisw tin teliki idea gia aftin tin apli kriptografisi, ekana ena dokimastiko. Skeftika na ftiaksw 2 monogiastatous pinakes (pou tha leitourgoun san strings), to Line1[95] kai Line2[95]. Afou tous diavasei apo to config.txt, tha tous ektipwsei stin console (eitei ola ta stoixeia tous eite 1 kata aitima). Kati omws fenetai na einai lathos. O compiler den vgazei sfalma, alla to programma "krasarei" sta Windows ME :( :(

 

Gia na dw pou iparxei to provlima, evala printf("1"), printf("2"), kait printf("3"). To programa krasarei epeita apo to "1".

 

Ena akoma parakseno einai oti ef'oson dilwnw init i; , kai sto telos, to seimeio pou to xrisimopoiw einai "sxoliasmeno" (/* ... */), o compiler den vgazei warning :|

 

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


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

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

printf("1");

while (!feof(Cfg))
{
	fscanf(Cfg, "%c", Line1[95]);
	fscanf(Cfg, "%c", Line1[95]);
}

printf("2");


//opoiadipote apo tis 2 akolouthes grammes den vgazei lathos ston compiler
//alla kanei to programa na krasarei sta WinME
printf("%c", Line1[95]); 
printf("%c", Line1[4]);

printf("3");

//etsi dimiourgisa tin proti grami tou config.txt, einai vasika o tropos pou einai
//topothetimena stin seira oi xaraktires tis ASCII

/*
for (i=32; i<=126; i++)
{
	fprintf(outF, "%c", i);
}
*/
}

 

To arxeio config.txt exei to ekseis periexomeno:

 

> !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
`1234567890-=QWERTYU IOP[]\ASDFGHJKL;'ZXCVBNM,./~!@#$%^&*()_+qwertyuiop{}|asdfghjkl:"zxcvbnm<>?

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

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

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