THMMY.gr

Ηλεκτρονικοί Υπολογιστές και Τεχνικά Θέματα => C / C++ / C# => Topic started by: Themis on September 18, 2012, 03:14:19 am



Title: C πρόβλημα
Post by: Themis on September 18, 2012, 03:14:19 am
Λοιπον. Εχω το εξής θέμα με ένα πρόγραμμα μου στη C.

        int bytes_read;
   int rv;
   int nchars=200;/*max possible number for the input of the user*/
   size_t nbytes=(sizeof(char))*nchars; /*size of chars in bytes*/
   char *commands[2];
   char *line=(char*) malloc(nbytes+1);
   bytes_read=getline(&line,&nbytes,stdin);/*read line from stdin*/
   if(bytes_read == -1){printf("Read line error");exit(-1);}/*error handling for bytes_read*/
   else{
      if(line[strlen(line-1)]=='\n'){
               line[strlen(line-1)]='\0';/*change new line character in the end of the line of stdin*/
            }}
   if(strcmp(line,"exit")==0){
            rv=3;
            exit(rv);
   }
   commands[0]=line;
   commands[1]=(char*)NULL;
   execvp(commands[0],commands);
   perror("Execution error");
   exit(-1);


Μπορεί κάποιος να μου τι γίνεται λάθος στη κοκκινη γραμμή και μου βγάζει error : not such a file or directory η  execvp ενώ όταν βάλω πχ απλά commands[0]="ls"; όλα κομπλέ??????


Title: Re: C πρόβλημα
Post by: 4Dcube on September 18, 2012, 04:58:15 am
μήπως δεν έχεις δεσμεύσει καλά τη μνήμη;
αντί να δηλώσεις
Code:
char *line=(char*) malloc(nbytes+1);
ξέχνα το line και βάλε κατευθείαν
Code:
commands[0]=(char*) malloc(nbytes+1);

ή κάντα και τα δυο ξερωγω


Title: Re: C πρόβλημα
Post by: fugiFOX on September 18, 2012, 08:46:34 am
dokimase
commands = line

επίσης η αντιγραφή string στη C γίνειται με την strcpy()
και όχι απευθείας ανάθεση


Title: Re: C πρόβλημα
Post by: zisis00 on September 18, 2012, 12:52:15 pm
Λοιπον. Εχω το εξής θέμα με ένα πρόγραμμα μου στη C.

        int bytes_read;
   int rv;
   int nchars=200;/*max possible number for the input of the user*/
   size_t nbytes=(sizeof(char))*nchars; /*size of chars in bytes*/
   char *commands[2];
   char *line=(char*) malloc(nbytes+1);
   bytes_read=getline(&line,&nbytes,stdin);/*read line from stdin*/
   if(bytes_read == -1){printf("Read line error");exit(-1);}/*error handling for bytes_read*/
   else{
      if(line[strlen(line-1)]=='\n'){
               line[strlen(line-1)]='\0';/*change new line character in the end of the line of stdin*/

            }}
   if(strcmp(line,"exit")==0){
            rv=3;
            exit(rv);
   }
   commands[0]=line;
   commands[1]=(char*)NULL;
   execvp(commands[0],commands);
   perror("Execution error");
   exit(-1);


Μπορεί κάποιος να μου τι γίνεται λάθος στη κοκκινη γραμμή και μου βγάζει error : not such a file or directory η  execvp ενώ όταν βάλω πχ απλά commands[0]="ls"; όλα κομπλέ??????

Το λάθος σου έιναι αυτό που έκανα bold. Η getline() κρατάει και το \n γι'αυτό η execvp σου πετάει ότι νά 'ναι. Το if(line[strlen(line-1)]=='\n' πρέπει να γίνει if(line[ strlen(line) - 1 ] == '\n'). Το ίδιο πρέπει να κάνεις και στη σειρά από κάτω για να σου τρέξει σωστά.. Είναι προφανές τι γίνεται λάθος και γαμιέται..
dokimase
commands = line

επίσης η αντιγραφή string στη C γίνειται με την strcpy()
και όχι απευθείας ανάθεση
Τo commands = line θα πετάξει error γιατι το commands είναι array of pointers ενώ το line είναι απλός pointer. Το commands[0] = line μπορεί να μην αντιγράφει (όπως σωστά λες) το line στο command, αναθέτει όμως την τιμη του line (εκει που δείχνει το line, δηλαδή στην εντολή που θα διαβάσει από το stdin) στο commands[0] και μπορείς να χρησιμοποιείς το comammand[0] αντι του line.


Title: Re: C πρόβλημα
Post by: BOBoMASTORAS on September 18, 2012, 14:27:12 pm
επίσης συχνό πρόβλημα:

η exec* δεν έχει ορισμένη την μεταβλητή PATH. Ως εκ δε μπορεί να βρει που είναι το εκτελέσιμα για να τα εκτελέσει. Βάλε full path ή όρισε την μεταβλητή PATH με την setenv.


Title: Re: C πρόβλημα
Post by: SolidSNK on September 18, 2012, 16:46:35 pm
επίσης συχνό πρόβλημα:

η exec* δεν έχει ορισμένη την μεταβλητή PATH. Ως εκ δε μπορεί να βρει που είναι το εκτελέσιμα για να τα εκτελέσει. Βάλε full path ή όρισε την μεταβλητή PATH με την setenv.
Όχι όλες, εκείνες που δεν τελειώνουν σε "e", παίρνουν το environment από την calling process, η οποία αναμένεται να έχει set το PATH.

Btw Themis για input θα χρησιμοποιούσα την πιο συνηθισμένη fgets (όχι πως η getline έχει θέμα), ενώ για debug τον gdb.


Title: Re: C πρόβλημα
Post by: BOBoMASTORAS on September 19, 2012, 13:08:25 pm
επίσης συχνό πρόβλημα:

η exec* δεν έχει ορισμένη την μεταβλητή PATH. Ως εκ δε μπορεί να βρει που είναι το εκτελέσιμα για να τα εκτελέσει. Βάλε full path ή όρισε την μεταβλητή PATH με την setenv.
Όχι όλες, εκείνες που δεν τελειώνουν σε "e", παίρνουν το environment από την calling process, η οποία αναμένεται να έχει set το PATH.

nop

The execle() and execvpe() functions allow the caller to specify the environment of the executed program via the argument envp. The envp argument is an array of pointers to null-terminated strings and must be terminated by a NULL pointer. The other functions take the environment for the new process image from the external variable environ in the calling process.


Title: Re: C πρόβλημα
Post by: Themis on September 19, 2012, 13:59:57 pm
Λοιπον. Εχω το εξής θέμα με ένα πρόγραμμα μου στη C.

        int bytes_read;
   int rv;
   int nchars=200;/*max possible number for the input of the user*/
   size_t nbytes=(sizeof(char))*nchars; /*size of chars in bytes*/
   char *commands[2];
   char *line=(char*) malloc(nbytes+1);
   bytes_read=getline(&line,&nbytes,stdin);/*read line from stdin*/
   if(bytes_read == -1){printf("Read line error");exit(-1);}/*error handling for bytes_read*/
   else{
      if(line[strlen(line-1)]=='\n'){
               line[strlen(line-1)]='\0';/*change new line character in the end of the line of stdin*/

            }}
   if(strcmp(line,"exit")==0){
            rv=3;
            exit(rv);
   }
   commands[0]=line;
   commands[1]=(char*)NULL;
   execvp(commands[0],commands);
   perror("Execution error");
   exit(-1);


Μπορεί κάποιος να μου τι γίνεται λάθος στη κοκκινη γραμμή και μου βγάζει error : not such a file or directory η  execvp ενώ όταν βάλω πχ απλά commands[0]="ls"; όλα κομπλέ??????

Το λάθος σου έιναι αυτό που έκανα bold. Η getline() κρατάει και το \n γι'αυτό η execvp σου πετάει ότι νά 'ναι. Το if(line[strlen(line-1)]=='\n' πρέπει να γίνει if(line[ strlen(line) - 1 ] == '\n'). Το ίδιο πρέπει να κάνεις και στη σειρά από κάτω για να σου τρέξει σωστά.. Είναι προφανές τι γίνεται λάθος και γαμιέται..
dokimase
commands = line

επίσης η αντιγραφή string στη C γίνειται με την strcpy()
και όχι απευθείας ανάθεση
Τo commands = line θα πετάξει error γιατι το commands είναι array of pointers ενώ το line είναι απλός pointer. Το commands[0] = line μπορεί να μην αντιγράφει (όπως σωστά λες) το line στο command, αναθέτει όμως την τιμη του line (εκει που δείχνει το line, δηλαδή στην εντολή που θα διαβάσει από το stdin) στο commands[0] και μπορείς να χρησιμοποιείς το comammand[0] αντι του line.

Αυτό με το line[strlen(line-1)] ήταν το πρόβλημα. Ευχαριστώ πολύ παιδιά για την βοήθεια. ΤΗΜΜΥ μετράει αν και είχα καιρο να το χρησιμοποιήσω. Θα συνεχίσω να σας προτιμώ αλάνια.