Jump to content



Βοήθεια στην C


Thodoris21

Recommended Posts

Καλησπέρα παιδιά.Το πρόβλημα είναι το εξής:

Διαβάζω ένα αρχείο στην 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

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

Δες τι είχα κάνει εγώ:

#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

 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 mode

ask5.c:42:3: note: use option -std=c99 or -std=gnu99 to compile your code

Link to comment
Share on other sites

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

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

Δες τι είχα κάνει εγώ:

#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

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

Το τροποποίησα έτσι αλλά δεν παίζει...Παγώνει το 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

Εμένα αυτός ο κώδικας μου φαίνεται σωστός αλλά για κάποιο λόγο όταν κάνω 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


ch = getc(fd);
if (ch == '/') {
while (ch != '\n') {
putc('@',fd1);
}
ch = getc(fd);
}

Το χρησιμοποιει όταν το σχόλιο αρχίζει με // που ειναι το σχόλιο που πιάνει μόνο μια γραμμή.Μήπως απλώς αργεί?Μην ξεχνάς ελέγχει χαρακτήρα χαρακτήρα το αρχείο.

Link to comment
Share on other sites

Θελω ο παραπανω κωδικας να εκτελειται απο 3 διεργασιες και καθε διεργασια να εκτελει το 1/3 του κωδικα.Η 2η διεργασια το αλλο 1/3 κτλ...

Εχει κανεις καμια ιδεα πως γινεται?

Link to comment
Share on other sites

Ναι οι διεργασιες εκτελουνται παραλληλα αλλά το διάβασμα από το αρχικό αρχείο και το γράψιμο στο τελικό θα πρέπει να "προστατεύεται" από δύο σημαφόρους, έναν για το διάβασμα και έναν για το γράψιμο. Κάθε διεργασία θα προσπαθεί αρχικά να κάνει down() το σημαφόρο του διαβάσματος, θα πηγαίνει τον κέρσορα στο επόμενο χαρακτήρα από αυτόν που είχε διαβάσει (στο αρχικό αρχείο), θα τον διαβάζει, θα κάνει up() τον σημαφόρο του διαβάσματος και έπειτα θα κάνει down() το σημαφόρο του γραψίματος, θα πηγαίνει τον κέρσορα στην ίδια θέση με αυτή από την οποία διάβασε τον χαρακτήρα (στο αρχείο tmp), θα γράφει το γράμμα (ή τον ειδικό χαρακτήρα αν αυτό που διάβασε είναι σχόλιο) και τέλος θα κάνει up() το σημαφόρο γραψίματος.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

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

Important Information

Ο ιστότοπος theLab.gr χρησιμοποιεί cookies για να διασφαλίσει την καλύτερη εμπειρία σας κατά την περιήγηση. Μπορείτε να προσαρμόσετε τις ρυθμίσεις των cookies σας , διαφορετικά θα υποθέσουμε ότι είστε εντάξει για να συνεχίσετε.