2013-04-18 4 views
9

Hier ist Code, der den Cd-Systemaufruf mit C implementiert. Das Problem mit diesem Code ist, dass es nicht die if und ich kann nicht verstehen, warum.Implementierung von CD-Systemanruf mit C- If-Bedingung

#include<sys/stat.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include<dirent.h> 
#include<error.h> 

#define BUFFERSIZE 20 
int main(){ 

char *args[80]; 
char buffer[BUFFERSIZE]; 
char *prompt = "OS"; 
char *a = ">"; 
printf("%s%s",prompt,a); 
fgets(buffer, BUFFERSIZE, stdin); 

char *tok; 
tok = strtok (buffer," "); 


while(buffer != NULL){ 
    buffer[strlen(buffer)-1] = '\0'; 
    pid_t pid; 
    pid = fork(); 
    if(pid < 0){ 
     fprintf(stderr, "Fork failed"); 
     return 1; 
    } 
    else if(pid == 0){ 

     if(strcmp(buffer,"cd") == 0){ 
     tok = strtok(NULL,"\n"); 
     cd(tok); 
     } 
     printf("%s%s",prompt,a); 
     fgets(buffer, BUFFERSIZE, stdin); 
    } 
    else{ 
    wait(NULL); 
    } 
} 
return 0; 
} 


int cd(char *pth){ 
    char path[1000]; 
    strcpy(path,pth); 

    static char *prompt = "OS"; 
    static char *a = ">"; 
    char *token; 

    char cwd[256]; 
    getcwd(cwd,sizeof(cwd)); 

    strcat(cwd,"/"); 
    strcat(cwd,path); 
    chdir(cwd);  

    printf("%s-%s%s",prompt,path,a); 
    return 0; 
    } 
+1

F: Haben Sie sich den Wert von "temp" in Ihrem Debugger der Wahl angesehen? Ist es tatsächlich gleich "cd"? Hier ist ein gutes Tutorial für "gdb": http://www.cs.cmu.edu/~gilpin/tutorial/ – paulsm4

+4

1) 'Puffer [strlen (Puffer) -1] = '\ 0';' Schlechte Angewohnheit, IMHO . strlen() * könnte * null zurückgeben. 2) 'tok = strtok (temp," ");' tok Schatten ein anderes 'tok' – wildplasser

+2

' cd' * kann kein eigenständiges Programm sein, es muss eine eingebaute Shell sein. Was genau versuchst du zu tun? –

Antwort

6

Haben die Logik nach Anregungen von anderen aktualisiert.

Es gibt keine Notwendigkeit für ein Kind Prozess hier. Wenn Sie Multitasking benötigen, dann verwenden Sie Threads. Child process may be required for process running in background.

Das folgende Programm ist für mich arbeiten:

#include <stdio.h> 

#include <sys/stat.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <dirent.h> 
//#include <error.h> 

int hasPrefix(char const *, char const *); 
int cd(char *pth); 

#define BUFFERSIZE 200 
int main(){ 

    char buffer[BUFFERSIZE]; 
    char *prompt = "OS"; 
    char *a = ">"; 

    char *tok; 
    tok = strtok (buffer," "); 


    while(buffer != NULL){ 
     bzero(buffer, BUFFERSIZE); 
     printf("%s%s",prompt,a); 
     fgets(buffer, BUFFERSIZE, stdin); 
     if(hasPrefix(buffer,"cd") == 0){ 
      tok = strchr(buffer,' '); //use something more powerful 
      if(tok) { 
       char *tempTok = tok + 1; 
       tok = tempTok; 
       char *locationOfNewLine = strchr(tok, '\n'); 
       if(locationOfNewLine) { 
        *locationOfNewLine = '\0'; 
       } 
       cd(tok); 
      } 
     }else{ 
      system("ls"); //for testing the CWD/PWD 
     } 
    } 
    return 0; 
} 

int hasPrefix(char const *p, char const *q) 
{ 
    int i = 0; 
    for(i = 0;q[i];i++) 
    { 
     if(p[i] != q[i]) 
      return -1; 
    } 
    return 0; 
} 

int cd(char *pth){ 
    char path[BUFFERSIZE]; 
    strcpy(path,pth); 

    char cwd[BUFFERSIZE]; 
    if(pth[0] != '/') 
    {// true for the dir in cwd 
     getcwd(cwd,sizeof(cwd)); 
     strcat(cwd,"/"); 
     strcat(cwd,path); 
     chdir(cwd); 
    }else{//true for dir w.r.t./
     chdir(pth); 
    } 

    return 0; 
} 
+0

danke eine million .. das war sehr hilfreich .... – urwaCFC

+3

Was ist falsch mit dem Standard 'strcmp()', dass das Schreiben seiner eigenen erfordert. – Barmar

+0

Sie sollten nicht vorgeschlagen haben, ein Homebrew 'mystrcmp' zu verwenden, und Sie haben versehentlich nur warum gezeigt. Der Standard 'strcmp' hat hier nichts falsch, während deins das tut. Es hat zwei Bugs: 1. Wenn 'q' eine leere Zeichenkette (' '' ') ist, melden Sie immer Gleichheit und 2. Wenn die Zeichenkette' p' die Zeichenkette 'q' als Präfix hat, aber nachfolgende zusätzliche Zeichen hat , wird es Gleichheit berichten. Es wäre besser gewesen, den Zeilenumbruch mit diesem One-Liner von 'fgets() 'abzuhacken (http://stackoverflow.com/a/28462221/2809095). –

1

Ich denke, das Problem, weil diese Linie ist:

buffer[strlen(buffer)-1] = '\0'; 

Dies ersetzt das letzte Zeichen von buffer mit einem Null-Zeichen. Also, wenn buffer enthalten "cd", enthält es jetzt nur "c" (da das Nullzeichen ist der String-Terminator in C).

Es scheint keine Notwendigkeit für diese Aussage, nur entfernen Sie es.

+0

Gerade ist darüber gestolpert, und das ist wirklich die einzig richtige Antwort. –

2

Verwenden

... 
if(strncmp(buffer,"cd",2) == 0){ 
... 

statt. Es ist gut, Präfixe beliebiger Länge zu vergleichen. Es gibt auch eine Grenze für die String-Größe. Keine Notwendigkeit, eine eigene Vergleichsroutine zu erstellen.

Sie haben andere Probleme im Code, aber diese können separat angesprochen werden.

Verwandte Themen