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

Αρχεία .doc στη C


FrAcTaL-gR

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

Λοιπόν, είπα να δοκιμάσω να διαβάσω ένα αρχείο .doc με το ακόλουθο πρόγραμμα

 

>
#include <stdio.h>

#define SIZE 20

int main ( void )
{
FILE *read;
FILE *write;
int c;
char input[ SIZE ];
char output[ SIZE ];

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( output, write );


while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
   }


return 0;
}

το helloworld.doc περιέχει μόνο τη φράση helloworld!

το helloword2.doc που παράγεται περιέχει τη φράση ZZϊZZϊZZϊZZϊZZϊΠΟ ΰ΅±

στην οθόνη το πρόγραμμα δεν εμφανίζει απολύτως τίποτε (ο τερματισμός του προγράμματος γίνεται κανονικά)

Τι πρόβλημα υπάρχει εδώ;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Τώρα που το λές, μου φαίνεται ΤΡΟΜΕΡΑ περίεργο, ένα αρχείο που περιέχει συνολικά 12 χαρακτήρες (μαζί με τον '\n' ) να έχει τόσο μεγάλο μέγεθος (δηλαδή 20ΚΒ).

 

Πάντως, έβαλα #define SIZE 20000 και το αποτέλεσμα ήταν οτι το helloword2.doc περιείχε 5 σελίδες με τα "κινέζικα". Μετά το έβαλα στο 25000 και είχα 6 σελίδες "κινέζικα". Και στην οθόνη πάλι τίποτα.

 

Θα δοκιμάσω να μετρήσω τους χαρακτήρες του helloword.doc με το πρόγραμμα και θα επανέλθω.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κάτσε μισό λεπτό.. Το doc πως το δημιούργησες; Με το Office έτσι; ΑΝ είναι έτσι τότε δεν έχει μόνο τους 12 χαρακτήρες που λες. Τα αρχεία doc περιέχουν και άλλες πληροφορίες που αφορούν την μορφοποίηση του κειμένου,την γραμματοσειρά κλπ.

 

Αν θες να δεις το ακριβές μέγεθος του αρχείου, δες το από τις ιδιότητές του...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ορίστε και η εκδοχή που μετρά τους χαρακτήρες του helloworld.doc

>
#include <stdio.h>

#define SIZE 25000

int main ( void )
{
FILE *read;
FILE *write;
int c;
char input[ SIZE ];
char output[ SIZE ];
int count = 0;

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( output, write );


while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
	count++;
   }

printf ( "to arxeio periexei %d xaraktires\n", count );


return 0;
}

Το αποτέλεσμα στην έξοδο είναι απογοητευτικό"

"to arxeio periexei 0 xaraktires

 

Τι δεν πάει καλά;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μετά από αντιγραφή που κάνεις και πριν από τον βρόγχο που μετράς το μήκος θα πρέπει να βάλεις και μια fseek για να επανέλθουμε στην αρχή του αρχείου.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μετά από αντιγραφή που κάνεις και πριν από τον βρόγχο που μετράς το μήκος θα πρέπει να βάλεις και μια fseek για να επανέλθουμε στην αρχή του αρχείου.

Ουππςςς!!! πως φαίνεται ο αρχάριος ε;

 

Προτίμησα την rewind ( ), μας κάνει ε;

>
#include <stdio.h>

#define SIZE 25000

int main ( void )
{
FILE *read;
FILE *write;
int c;
char input[ SIZE ];
char output[ SIZE ];
int count = 0;

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( output, write );

rewind ( read );

while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
	count++;
   }

printf ( "\n\nto arxeio periexei %d xaraktires\n", count );


return 0;
}

 

Και το αποτέλεσμα είναι:

Στο αρχείο helloword2.doc έχουμε 6 σελίδες με "κινέζικα"

Στην stdout έχουμε ακριβώς 6 "κινέζικους" χαρακτήρες και

"to arxeio periexei 6 xaraktires"

 

Α, ρε Bill (Gates) σκέτη καταστροφή είσαι!!! ( ή μήπως φταίω εγώ άραγε;)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Συγχώρεσέ με αλλά δεν ξέρω καθόλου C/C++ :o :o :o ...

 

Λόγω ομοιότητας με την Pascal, μπορώ να την καταλάβω και να δω τη ροή ενός προγράμματος, ίσως και να εντοπίσω κάποιο κραυγαλέο λάθος!

 

Τελικά ένα ένα θα στα πω, με το τσιγκέλι! Ουφ! :-D

 

Κάποια στιγμή πρέπει να κάνεις και κανά fclose τα ήδη ανοιχτά αρχεία... Βάλε και στο SIZE ακριβώς το μέγεθος του αρχείου. Δέν ξέρω τι άλλο να πω!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

κοιτα, τα αρχεια του word δεν ειναι ascii, ειναι binary. Αυτο σημαίνει πως δε μπορεις να διαβασεις ετσι απλα τους χαρακτηρες που εγραψες. Για να διαβασεις ενα binary αρχειο, πρεπει να ξερεις το φορματ του , δηλαδη το πως ειναι τοποθετημενα τα δεδομενα μεσα του. Δεν το εχω πολυψαξει αλλα νομιζω πως το format του word ειναι proprietary, συνεπως δεν θα το βρεις ετσι απλα διαθεσιμο στο νετ (σου ξαναλεω ομως πως δεν ειμαι σιγουρος)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Απ'οτι φαίνεται περισσότερη σημασία έχει να έχεις εμπειρία στον προγραμματισμό, παρά σε κάποια συγκεκριμένη γλώσσα. Ηδη έριξα 2 μούντζες :-) στον εαυτό μου (για τα ανοικτά αρχεία), μετά άλλαξα τη τιμή του SIZE, μετά έκλεισα τα αρχεία, και μετά (από περιέργεια) έβαλα να τυπωθούν στην stdout τα 10 πρώτα στοιχεία των πινάκων input και output.

 

>
#include <stdio.h>

#define SIZE 19968

int main ( void )
{
FILE *read;
FILE *write;
int c, i;
char input[ SIZE ];
char output[ SIZE ];
int count = 0;

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( output, write );

rewind ( read );

while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
	count++;
   }
fclose ( read );
fclose ( write );

printf ( "\n\nto arxeio periexei %d xaraktires\n", count );

for ( i = 0; i < 10; i++ )
{
	printf ( "input[%d] = %c\t", i, input[ i ] );
	printf ( "output[%d] = %c\n", i, output[ i ] );
}


return 0;
}

Αποτελέσματα

αρχείο helloworld2.doc : 5 σελίδες "κινέζικα"

stdout :

1) 6 ¨κινέζικοι" χαρακτήρες

2) to arxeio periexei 6 xaraktires

3) Τα input[ i ] συμπτίπτουν με το 1)

6) Τα output[ i ] είναι "άσχετα κινέζικα" (περιλαμβάνει μόνο 'Ζ' και '.')

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

κοιτα, τα αρχεια του word δεν ειναι ascii, ειναι binary. Αυτο σημαίνει πως δε μπορεις να διαβασεις ετσι απλα τους χαρακτηρες που εγραψες. Για να διαβασεις ενα binary αρχειο, πρεπει να ξερεις το φορματ του , δηλαδη το πως ειναι τοποθετημενα τα δεδομενα μεσα του. Δεν το εχω πολυψαξει αλλα νομιζω πως το format του word ειναι proprietary, συνεπως δεν θα το βρεις ετσι απλα διαθεσιμο στο νετ (σου ξαναλεω ομως πως δεν ειμαι σιγουρος)

 

Δεν αντιλέγω (του το επισήμανα και πιο πάνω μερικώς), αλλά εάν έκλεινε τα ανοιχτά αρχεία, νομίζω πως δεν θα είχε πρόβλημα τουλάχιστον στην αντιγραφή...:rolleyes:

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δεν έχεις καταλάβει μάλλον ότι το DOC δεν είναι ένα plain-text format, αλλά η πληροφορία σε αυτό είναι κωδικοποιημένη με proprietary τρόπο. Κοινώς, η Microsoft:

 

1. Δεν έχει εκδώσει δημοσίως specifications που να περιγράφουν το format (κάτι που σημαίνει ότι δε μπορείς να φτιάξεις πρόγραμμα σε C ή οποιαδήποτε άλλη γλώσσα που να διαβάζει αξιόπιστα τα περιεχόμενα ενός DOC αρχείου)

2. Σε αρκετές εκδόσεις του Microsoft Word άλλαζε τη σύμβαση κωδικοποίησης, σπάζοντας την προς τα πίσω συμβατότητα. Μόνο τελευταία κινείται προς την κατεύθυνση ενός πιο αυστηρού standardization βασιζόμενη σε XML

 

Μάλλον ξεφεύγω από το θέμα, όμως. Το ζουμί είναι ότι δε μπορείς να δουλέψεις με τη λογική «1 byte = 1 χαρακτήρας» του κώδικα που παρουσίασες σε DOC αρχεία. Μόνο σε ASCII (ή αλλιώς, plain-text) αρχεία. Δες τα παρακάτω links για περισσότερες πληροφορίες :

 

http://en.wikipedia.org/wiki/Plain_text

http://en.wikipedia.org/wiki/ASCII

http://en.wikipedia.org/wiki/DOC_(computing)

 

 

 

ΥΓ : Αν δεν κάνω λάθος, σε άλλο thread διάβασα ότι δεν έχεις formal training στον προγραμματισμό και έχεις ξεκινήσει MSc σε Πληροφορική. Πιθανόν να αντιμετωπίσεις αρκετά τέτοια φαινόμενα παρανοήσεων και να απογοητεύεσαι. Η συμβουλή μου: Αφιέρωσε λίγο χρόνο για να επιμορφωθείς κατά το δυνατόν σε τομείς που αποτελούν το «σκληρό πυρήνα» της Πληροφορικής, όπως Αρχιτεκτονική Η/Υ και Δομές Δεδομένων. Αν μάλιστα δεν προέρχεσαι από Θετική Επιστήμη, μερικά Μαθηματικά θα είναι επίσης απαραίτητα. Κατά τα άλλα, πάρε το σιγά-σιγά και ζήτα βοήθεια εδώ στο φόρουμ όποτε το κρίνεις αναγκαίο. Υπάρχουν πολλά αξιόλογα μέλη με διάθεση για βοήθεια.

 

ΥΓ2 : Εύχομαι καλή χρονιά!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

ευχαριστώ για τις απαντήσεις σας, νομιζω πως καταλαβαίνω το πρόβλημα

Παντως ξανακοιτώντας τον κώδικα, βλέπω πως δεν χρειάζομαι καθόλου τον πίνακα output (οι τιμές του περιείχαν "σκουπίδια").

Ετσι ο κώδικας τώρα είναι ως εξής

>
#include <stdio.h>

#define SIZE 19968

int main ( void )
{
FILE *read;
FILE *write;
int c, i;
char input[ SIZE ];
int count = 0;

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( input, write );

rewind ( read );

while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
	count++;
   }
fclose ( read );
fclose ( write );

printf ( "\n\nto arxeio periexei %d xaraktires\n", count );

for ( i = 0; i < 10; i++ )
	printf ( "input[%d] = %c\t", i, input[ i ] );




return 0;
}

Και τώρα έχω τις εξης νέα στοιχεία (που επιβεβαιώνουν τους προλαλήσαντες)

Οταν ανοιγω (με το MSWord) το hellowold2.doc , μου βγάζει το μύνημα

"Επιλέξτε την κωδικοποίηση που καθιστά αναγνώσιμο το έγγραφο".

Στις "ιδιότητες" του hellowold2,doc , το μέγεθος του είναι ακριβώς 12 bytes (όσο το helloworls.doc.

 

Αυτα, και σας ευχαριστώ και πάλι για τις απαντήσεις σας.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

ευχαριστώ για τις απαντήσεις σας, νομιζω πως καταλαβαίνω το πρόβλημα

Παντως ξανακοιτώντας τον κώδικα, βλέπω πως δεν χρειάζομαι καθόλου τον πίνακα output (οι τιμές του περιείχαν "σκουπίδια").

Ετσι ο κώδικας τώρα είναι ως εξής

>
#include <stdio.h>

#define SIZE 19968

int main ( void )
{
FILE *read;
FILE *write;
int c, i;
char input[ SIZE ];
int count = 0;

if ( ( read = fopen ( "helloworld.doc", "r" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

if ( ( write = fopen ( "helloworld2.doc", "w" ) ) == NULL )
{
	printf ( "can't open file\n" );
	return -2;
}

fgets ( input, SIZE, read );
fputs ( input, write );

rewind ( read );

while ( ( c = fgetc ( read ) ) != EOF )
{
	putc ( c, write );
	printf ( "%c", c );
	count++;
   }
fclose ( read );
fclose ( write );

printf ( "\n\nto arxeio periexei %d xaraktires\n", count );

for ( i = 0; i < 10; i++ )
	printf ( "input[%d] = %c\t", i, input[ i ] );




return 0;
}

Και τώρα έχω τις εξης νέα στοιχεία (που επιβεβαιώνουν τους προλαλήσαντες)

Οταν ανοιγω (με το MSWord) το hellowold2.doc , μου βγάζει το μύνημα

"Επιλέξτε την κωδικοποίηση που καθιστά αναγνώσιμο το έγγραφο".

Στις "ιδιότητες" του hellowold2,doc , το μέγεθος του είναι ακριβώς 12 bytes (όσο το helloworls.doc.

 

Αυτα, και σας ευχαριστώ και πάλι για τις απαντήσεις σας.

 

Τώρα που το είδα και πήγα να στο γράψω το είδες και μόνος σου!!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

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

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