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 του αρχείου.

Όποια βοήθεια δεκτή.

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

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

#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) ;

char test[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
for (int i = 0;i < strlen(test);i++)
{
test[i] = '@';
}

Αντικαθιστά κάθε χαρακτήρα στον πίνακα χαρακτήρων test με το @.

 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] = '@';
}
}
}

Για δοκίμασε αυτό

 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

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

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 αλλά δεν δουλεύει σωστά.

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

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

#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) ;

Λίγο βοήθεια στην τροποποίηση αν μπορείς...

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;
}
}

Δοκίμασε αυτό

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

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


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

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

Το εφτιαξα αυτο και μου αντικαθιστα τα σχολια ολα αλλα υπαρχει ακομα ενα προβληματακι.

Τα σχολια */αδα*/

τα αντικαθιστά έτσι @@@@@@/

Γιατι αραγε?

σημαφόροι και process σε linux? βλέπω τα race conditions και τα pid και τρομάζω.Τι θες να κάνεις?

Τα σχολια */αδα*/

τα αντικαθιστά έτσι @@@@@@/

C Comments ©

H "φράση" */αδα*/ δεν αποτελεί σχόλιο

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

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

Οι 3 διεργασίες εκτελούνται παράλληλα ή γραμμικά (η μια μετα την άλλη)?

Να εκτελεί τον κώδικα εννοείς να κάνει το 1/3 από τις γραμμές του αρχείου?

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

Archived

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

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

Important Information

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