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 του αρχείου.Όποια βοήθεια δεκτή. Link to comment Share on other sites More sharing options...
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) ; Link to comment Share on other sites More sharing options...
nucleus Μάϊος 12, 2012 #3 Κοινοποίηση Μάϊος 12, 2012 char test[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";for (int i = 0;i < strlen(test);i++){ test[i] = '@';}Αντικαθιστά κάθε χαρακτήρα στον πίνακα χαρακτήρων test με το @. Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 12, 2012 Author #4 Κοινοποίηση Μάϊος 12, 2012 Λίγο βοήθεια στην τροποποίηση αν μπορείς... Link to comment Share on other sites More sharing options...
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] = '@'; } } }Για δοκίμασε αυτό Link to comment Share on other sites More sharing options...
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 Link to comment Share on other sites More sharing options...
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 Link to comment Share on other sites More sharing options...
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 αλλά δεν δουλεύει σωστά. Link to comment Share on other sites More sharing options...
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) ;Λίγο βοήθεια στην τροποποίηση αν μπορείς... Link to comment Share on other sites More sharing options...
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; }}Δοκίμασε αυτό Link to comment Share on other sites More sharing options...
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); Link to comment Share on other sites More sharing options...
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); Link to comment Share on other sites More sharing options...
nucleus Μάϊος 12, 2012 #13 Κοινοποίηση Μάϊος 12, 2012 ch = getc(fd); if (ch == '/') { while (ch != '\n') { putc('@',fd1); } ch = getc(fd); }Το χρησιμοποιει όταν το σχόλιο αρχίζει με // που ειναι το σχόλιο που πιάνει μόνο μια γραμμή.Μήπως απλώς αργεί?Μην ξεχνάς ελέγχει χαρακτήρα χαρακτήρα το αρχείο. Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 12, 2012 Author #14 Κοινοποίηση Μάϊος 12, 2012 Το εφτιαξα αυτο και μου αντικαθιστα τα σχολια ολα αλλα υπαρχει ακομα ενα προβληματακι.Τα σχολια */αδα*/τα αντικαθιστά έτσι @@@@@@/Γιατι αραγε? Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 12, 2012 Author #15 Κοινοποίηση Μάϊος 12, 2012 Το βρήκα.Δουλεύει καλά τώρα!Ευχαριστώ! Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 13, 2012 Author #16 Κοινοποίηση Μάϊος 13, 2012 Γνωρίζει κανείς από διεργασίες και σημαφόρους στο linux? Link to comment Share on other sites More sharing options...
nucleus Μάϊος 13, 2012 #17 Κοινοποίηση Μάϊος 13, 2012 σημαφόροι και process σε linux? βλέπω τα race conditions και τα pid και τρομάζω.Τι θες να κάνεις?Τα σχολια */αδα*/τα αντικαθιστά έτσι @@@@@@/C Comments ©H "φράση" */αδα*/ δεν αποτελεί σχόλιο Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 13, 2012 Author #18 Κοινοποίηση Μάϊος 13, 2012 Θελω ο παραπανω κωδικας να εκτελειται απο 3 διεργασιες και καθε διεργασια να εκτελει το 1/3 του κωδικα.Η 2η διεργασια το αλλο 1/3 κτλ...Εχει κανεις καμια ιδεα πως γινεται? Link to comment Share on other sites More sharing options...
nucleus Μάϊος 13, 2012 #19 Κοινοποίηση Μάϊος 13, 2012 Οι 3 διεργασίες εκτελούνται παράλληλα ή γραμμικά (η μια μετα την άλλη)?Να εκτελεί τον κώδικα εννοείς να κάνει το 1/3 από τις γραμμές του αρχείου? Link to comment Share on other sites More sharing options...
Thodoris21 Μάϊος 13, 2012 Author #20 Κοινοποίηση Μάϊος 13, 2012 Ναι οι διεργασιες εκτελουνται παραλληλα αλλά το διάβασμα από το αρχικό αρχείο και το γράψιμο στο τελικό θα πρέπει να "προστατεύεται" από δύο σημαφόρους, έναν για το διάβασμα και έναν για το γράψιμο. Κάθε διεργασία θα προσπαθεί αρχικά να κάνει down() το σημαφόρο του διαβάσματος, θα πηγαίνει τον κέρσορα στο επόμενο χαρακτήρα από αυτόν που είχε διαβάσει (στο αρχικό αρχείο), θα τον διαβάζει, θα κάνει up() τον σημαφόρο του διαβάσματος και έπειτα θα κάνει down() το σημαφόρο του γραψίματος, θα πηγαίνει τον κέρσορα στην ίδια θέση με αυτή από την οποία διάβασε τον χαρακτήρα (στο αρχείο tmp), θα γράφει το γράμμα (ή τον ειδικό χαρακτήρα αν αυτό που διάβασε είναι σχόλιο) και τέλος θα κάνει up() το σημαφόρο γραψίματος. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.