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

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

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

  • 0
FrAcTaL-gR

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

Ερώτηση

Λοιπόν, είπα να δοκιμάσω να διαβάσω ένα αρχείο .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ϊΠΟ ΰ΅±

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

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

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

Απ'οτι φαίνεται περισσότερη σημασία έχει να έχεις εμπειρία στον προγραμματισμό, παρά σε κάποια συγκεκριμένη γλώσσα. Ηδη έριξα 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.

 

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Άλλαξε το SIZE και βάλτο ίσο με το μέγεθος του αρχείου σε μπαιτ...

 

Ένα doc απο-και-κλείεται να έχει τόσο μικρό μέγεθος.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

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

 

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

 

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Κάτσε μισό λεπτό.. Το doc πως το δημιούργησες; Με το Office έτσι; ΑΝ είναι έτσι τότε δεν έχει μόνο τους 12 χαρακτήρες που λες. Τα αρχεία 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.

 

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

 

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Οντως το αρχείο δημιουργήθηκε από το MSOffice, και από τις ιδιότητές είδα οτι έχει μέγεθος 20ΚΒ.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ορίστε και η εκδοχή που μετρά τους χαρακτήρες του 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

 

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Όπως είπαν και οι προηγούμενοι φίλοι, δεν μπορείς δυστυχώς να διαβάσεις κατευθείαν τα αρχεία DOC του MS-Word καθώς δεν πρόκειται για ASCII κείμενο αλλά για ένα εξαιρετικά εξειδικευμένο και πολύπλοκο format αποθήκευσης εγγραφών της Microsoft (βέβαια στις πρόσφατες εκδόσεις η MS αρχίζει και υποστηρίζει και έναν νέο τύπο DOC βασισμένο στην XML, που σαφώς είναι ευκολότερος στην δομή του -αν δεν κάνω λάθος).

 

Παρʼ όλα αυτά (μιας και πριν μερικά χρόνια χρειάσθηκε να γράψω κώδικα που δημιουργούσε αρχεία XLS Excel 1.0 ως αν θυμάμαι καλά 7.0 -ουσιαστικά ήταν το Lotus 1-2-3 format με κάποια MS extensions), αναρτώ το παρακάτω link που περιλαμβάνει μεταξύ άλλων και το DOC format των πιο γνωστών εκδόσεων του Microsoft Word για κάθε τολμηρό που θα θελήσει να το εφαρμόσει ή να το αναγνώσει:

 

http://www.wotsit.org/list.asp?search=DOC&button=GO%21

 

Καλή τύχη!!

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Μετά από αντιγραφή που κάνεις και πριν από τον βρόγχο που μετράς το μήκος θα πρέπει να βάλεις και μια 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) σκέτη καταστροφή είσαι!!! ( ή μήπως φταίω εγώ άραγε;)

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

ψάξε τον κώδικα του abiword, είναι open και free.

http://www.abisource.com/

και τον κώδικα του ted

http://www.nllgg.nl/Ted/

 

καλή χρονιά

 

.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

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

 

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

 

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

 

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

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
×
×
  • Δημιουργία νέου...