Thodoris21 Δημοσιεύτηκε Μάϊος 12, 2012 #1 Δημοσιεύτηκε Μάϊος 12, 2012 Καλησπέρα παιδιά.Το πρόβλημα είναι το εξής:Διαβάζω ένα αρχείο στην C και θέλω να σαρώνει γραμμή γραμμή και όποια γραμμή είναι σχόλιο,δηλαδή ξεκινάει με "//" ή "/*",να αντικαθιστά όσους χαρακτήρες έχει με το σύμβολο "@".Τέλος θα δημιουργεί ένα άλλο αρχείο ίδιο με το αρχικό με την διαφορά όπου έιχε το αρχικό σχόλια αυτο θα έχει @@@@@.Αυτό που έχω καταφέρει είναι να διαβάζει το αρχείο να σαρώνει γραμμή γραμμή,να βρίσκει τις γραμμές που αρχίζουν με σχόλιο αλλά κάθε γραμμή την αντικαθιστά μόνο με ένα @,ενώ εγώ θέλω όσους χαρακτήρες έχει η γραμμή τόσα παπάκια να βάζει.Ο κώδικας για την σάρωσει είναι παρακάτω: while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { strncpy (line,"@",sizeof(line)); } }Όπου line είναι ένας πίνακας που αποθηκεύονται οι γραμμές και fd ο file descriptor του αρχείου.Όποια βοήθεια δεκτή.
darien Μάϊος 12, 2012 #2 Μάϊος 12, 2012 Είχα κάνει μια παρόμοια εργασία κάποτε, μόνο που εγώ έπρεπε να διαγράψω τα σχόλια. Καλύτερα να παίρνεις έναν-έναν τους χαρακτήρες αντί για ολόκληρη γραμμή, θα είναι πιο εύκολο.Δες τι είχα κάνει εγώ:#include<stdio.h>#include<stdlib.h>int main(int argc, char *argv[]) { FILE *source,*output; char ch; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s input_file.c (output_file.c)", argv[0]); exit(-1); } source = fopen(argv[1], "r"); if (source == NULL) { fprintf(stderr, "Lathos kata to anoigma tou arxeiou.\n"); fprintf(stderr, "Usage: %s input_file.c (output_file.c)\n", argv[0]); exit(-1); } if (argc == 3) { output = fopen(argv[2], "w"); if (output == NULL) { fprintf(stderr, "Lathos kata to anoigma tou arxeiou.\n"); fprintf(stderr, "Usage: %s input_file.c (output_file.c)\n", argv[0]); exit(-1); } } ch = getc(source); while (ch != EOF) { if (ch == '/') { ch = getc(source); if (ch == '/') { while (ch != '\n') { ch = getc(source); } } if (ch == '*') { while (ch != EOF ) { ch = getc(source); if (ch == '*') { ch = getc(source); if (ch == '/') { break; } } } } ch = getc(source); } if (argc == 2) fputc(ch, stdout); if (argc == 3) putc(ch, output); ch = getc(source); }fclose(source);if (argc == 3) fclose(output);return(0);}Επειδή εγώ έπρεπε απλώς να τα σβήνω τα σχόλια, απλά προσπερνάω όλους τους χαρακτήρες της γραμμής που ξεκινάει με //ή το αντίστοιχο /* */ . Εσύ πρέπει να το τροποποιήσεις κατάλληλα ώστε αντι να προσπερνάει, να τυπώνει στην έξοδο @, δηλαδή πχ. putc('@', output) ;
nucleus Μάϊος 12, 2012 #3 Μάϊος 12, 2012 char test[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";for (int i = 0;i < strlen(test);i++){ test[i] = '@';}Αντικαθιστά κάθε χαρακτήρα στον πίνακα χαρακτήρων test με το @.
nucleus Μάϊος 12, 2012 #5 Μάϊος 12, 2012 while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { for (int i = 0;i < strlen(line);i++) { line[i] = '@'; } } }Για δοκίμασε αυτό
Thodoris21 Μάϊος 12, 2012 Author #6 Μάϊος 12, 2012 while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { for (int i = 0;i < strlen(line);i++) { line[i] = '@'; } } }Για δοκίμασε αυτόΧτυππάει...error: ‘for’ loop initial declarations are only allowed in C99 modeask5.c:42:3: note: use option -std=c99 or -std=gnu99 to compile your code
nucleus Μάϊος 12, 2012 #7 Μάϊος 12, 2012 while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { int i; for (i = 0;i < strlen(line);i++) { line[i] = '@'; } }}Try again
Thodoris21 Μάϊος 12, 2012 Author #8 Μάϊος 12, 2012 while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { int i; for (i = 0;i < strlen(line);i++) { line[i] = '@'; } }}Try againΚάνει compile αλλά δεν δουλεύει σωστά.
Thodoris21 Μάϊος 12, 2012 Author #9 Μάϊος 12, 2012 Είχα κάνει μια παρόμοια εργασία κάποτε, μόνο που εγώ έπρεπε να διαγράψω τα σχόλια. Καλύτερα να παίρνεις έναν-έναν τους χαρακτήρες αντί για ολόκληρη γραμμή, θα είναι πιο εύκολο.Δες τι είχα κάνει εγώ:#include<stdio.h>#include<stdlib.h>int main(int argc, char *argv[]) { FILE *source,*output; char ch; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s input_file.c (output_file.c)", argv[0]); exit(-1); } source = fopen(argv[1], "r"); if (source == NULL) { fprintf(stderr, "Lathos kata to anoigma tou arxeiou.\n"); fprintf(stderr, "Usage: %s input_file.c (output_file.c)\n", argv[0]); exit(-1); } if (argc == 3) { output = fopen(argv[2], "w"); if (output == NULL) { fprintf(stderr, "Lathos kata to anoigma tou arxeiou.\n"); fprintf(stderr, "Usage: %s input_file.c (output_file.c)\n", argv[0]); exit(-1); } } ch = getc(source); while (ch != EOF) { if (ch == '/') { ch = getc(source); if (ch == '/') { while (ch != '\n') { ch = getc(source); } } if (ch == '*') { while (ch != EOF ) { ch = getc(source); if (ch == '*') { ch = getc(source); if (ch == '/') { break; } } } } ch = getc(source); } if (argc == 2) fputc(ch, stdout); if (argc == 3) putc(ch, output); ch = getc(source); }fclose(source);if (argc == 3) fclose(output);return(0);}Επειδή εγώ έπρεπε απλώς να τα σβήνω τα σχόλια, απλά προσπερνάω όλους τους χαρακτήρες της γραμμής που ξεκινάει με //ή το αντίστοιχο /* */ . Εσύ πρέπει να το τροποποιήσεις κατάλληλα ώστε αντι να προσπερνάει, να τυπώνει στην έξοδο @, δηλαδή πχ. putc('@', output) ;Λίγο βοήθεια στην τροποποίηση αν μπορείς...
nucleus Μάϊος 12, 2012 #10 Μάϊος 12, 2012 while ( fgets ( line, sizeof line, fd ) != NULL ) { if ((strncmp (line,"//",strlen("//")) ==0) || (strncmp (line,"/*",strlen("/*")) ==0)) { char characterRead = test[i]; switch (characterRead) { case '/': characterRead = '/'; break; case '*': characterRead = '*'; break; default: characterRead = '@'; } test[i] = characterRead; }}Δοκίμασε αυτό
Thodoris21 Μάϊος 12, 2012 Author #11 Μάϊος 12, 2012 Το τροποποίησα έτσι αλλά δεν παίζει...Παγώνει το terminal!while (ch != EOF) { if (ch == '/') { ch = getc(fd); if (ch == '/') { while (ch != '\n') { putc('@',fd1); } } if (ch == '*') { while (ch != EOF ) { putc('@',fd1); if (ch == '*') { ch = getc(fd); if (ch == '/') { putc('@',fd1); } } } } ch = getc(fd); } putc(ch, fd1); ch = getc(fd); }fclose(fd);fclose(fd1);
Thodoris21 Μάϊος 12, 2012 Author #12 Μάϊος 12, 2012 Εμένα αυτός ο κώδικας μου φαίνεται σωστός αλλά για κάποιο λόγο όταν κάνω run παγώνει το terminal.Έχω την εντύπωση ότι σκαλώνει με το while (ch != '\n').ch = getc(fd); while (ch != EOF) { if (ch == '/') { ch = getc(fd); if (ch == '/') { while (ch != '\n') { putc('@',fd1); } ch = getc(fd); } if (ch == '*') { while (ch != EOF ) { putc('@',fd1); ch = getc(fd); if (ch == '*') { ch = getc(fd); if (ch == '/') { break; } } } } ch = getc(fd); } putc(ch, fd1); ch = getc(fd); }fclose(fd);fclose(fd1);
nucleus Μάϊος 12, 2012 #13 Μάϊος 12, 2012 ch = getc(fd); if (ch == '/') { while (ch != '\n') { putc('@',fd1); } ch = getc(fd); }Το χρησιμοποιει όταν το σχόλιο αρχίζει με // που ειναι το σχόλιο που πιάνει μόνο μια γραμμή.Μήπως απλώς αργεί?Μην ξεχνάς ελέγχει χαρακτήρα χαρακτήρα το αρχείο.
Thodoris21 Μάϊος 12, 2012 Author #14 Μάϊος 12, 2012 Το εφτιαξα αυτο και μου αντικαθιστα τα σχολια ολα αλλα υπαρχει ακομα ενα προβληματακι.Τα σχολια */αδα*/τα αντικαθιστά έτσι @@@@@@/Γιατι αραγε?
Thodoris21 Μάϊος 13, 2012 Author #16 Μάϊος 13, 2012 Γνωρίζει κανείς από διεργασίες και σημαφόρους στο linux?
nucleus Μάϊος 13, 2012 #17 Μάϊος 13, 2012 σημαφόροι και process σε linux? βλέπω τα race conditions και τα pid και τρομάζω.Τι θες να κάνεις?Τα σχολια */αδα*/τα αντικαθιστά έτσι @@@@@@/C Comments ©H "φράση" */αδα*/ δεν αποτελεί σχόλιο
Thodoris21 Μάϊος 13, 2012 Author #18 Μάϊος 13, 2012 Θελω ο παραπανω κωδικας να εκτελειται απο 3 διεργασιες και καθε διεργασια να εκτελει το 1/3 του κωδικα.Η 2η διεργασια το αλλο 1/3 κτλ...Εχει κανεις καμια ιδεα πως γινεται?
nucleus Μάϊος 13, 2012 #19 Μάϊος 13, 2012 Οι 3 διεργασίες εκτελούνται παράλληλα ή γραμμικά (η μια μετα την άλλη)?Να εκτελεί τον κώδικα εννοείς να κάνει το 1/3 από τις γραμμές του αρχείου?
Thodoris21 Μάϊος 13, 2012 Author #20 Μάϊος 13, 2012 Ναι οι διεργασιες εκτελουνται παραλληλα αλλά το διάβασμα από το αρχικό αρχείο και το γράψιμο στο τελικό θα πρέπει να "προστατεύεται" από δύο σημαφόρους, έναν για το διάβασμα και έναν για το γράψιμο. Κάθε διεργασία θα προσπαθεί αρχικά να κάνει down() το σημαφόρο του διαβάσματος, θα πηγαίνει τον κέρσορα στο επόμενο χαρακτήρα από αυτόν που είχε διαβάσει (στο αρχικό αρχείο), θα τον διαβάζει, θα κάνει up() τον σημαφόρο του διαβάσματος και έπειτα θα κάνει down() το σημαφόρο του γραψίματος, θα πηγαίνει τον κέρσορα στην ίδια θέση με αυτή από την οποία διάβασε τον χαρακτήρα (στο αρχείο tmp), θα γράφει το γράμμα (ή τον ειδικό χαρακτήρα αν αυτό που διάβασε είναι σχόλιο) και τέλος θα κάνει up() το σημαφόρο γραψίματος.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.