2012-01-16 15 views
3

私のコードで私を助けてください。私はcでsystem()関数を使用しています。 Cコードを使って新しいディレクトリを作成したいとしましょう。cでsystem()の変数を使用する方法

char name[]; 

printf("Enter the name of directory: "); 
scanf("%s", &name); 

はその後system()を使用して、私の代わりに新しいディレクトリryanを作るsystem("mkdir ryan");などの固定値を使用するか、または置くの name[]変数を使用したいです。ディレクトリの名前を作成して変数name[]に格納し、その値をryanの代わりに実装するとします。あなたの答えは高く評価されます。

+1

'system'は' mkdir'を呼び出すための正しい方法ではありません。呼び出しには完全に良い 'mkdir'関数があります。 'system'を使うと、はじめに導入されたことのないあらゆる種類のセキュリティ、堅牢性、パフォーマンスの問題につながります。基本的に、あなたは 'system'について聞いたことはないのです。 **絶対使用されるべきではありません**。 –

+2

あなたがそれを必要とする場合を除いて: – paxdiablo

答えて

-3

試してみてください。

char command[80]; 
strcpy(command, "mkdir "); 
strcat(command, name); 
system(command); 
+2

strcatをconst char *を最初のパラメータとして使用することはできません。 –

+0

@AhmedMasudおっと、アラートありがとう!今はいいですか? – wrongusername

+1

なぜそれがとても複雑になるのですかsnprintf –

0

まず第一に(とあなたのコードは一例であれば、これはおそらく問題ではありません)、これまで使用していない無制限%sscanf - バッファオーバーフローまであなたを開きます。

あなたのような文字列がある場合:

char name[] = "paxdiablo"; 

をあなただけの実行のために独自の文字列を構築するためにそれを使用することができます。

char cmd[1000]; 
strcpy (cmd, "mkdir "); 
strcat (cmd, name); 
system (cmd); 

そして、あなたはを知っている(またはstrlenに確認、または動的にそれは十分な大きさですので、バッファを割り当てる)を確認してくださいnameの大きあなたがそこにもバッファオーバーフローで終わるしないように。

ダイナミックアロケーション1の例:

void tryMkdir (char *dir) { 
    static char prefix[] = "mkdir "; 
    // Use sizeof to allow for null char at end. 
    char *cmd = malloc (sizeof (prefix) + strlen (dir)); 
    if (cmd != NULL) { 
     strcpy (cmd, prefix); 
     strcat (cmd, dir); 
     system (cmd); 
     free (cmd); 
    } 
} 

(おそらくmkdirmallocが失敗した場合に、そこにはいくつかのエラーチェックをしたいと思いますが)。

+0

snprintfで何が問題になりますか? –

+0

何もありません。仕事をする方法はたくさんあります。簡単な文字列の連結のために、私は 'snprintf'の完全な力よりむしろ' strcat'を優先します(バッファが十分に大きいので、ここで長さをチェックする必要はありません)。私は2つ以上のものから構成された文字列を構築していた場合、または長さの特定されていない場合、私はおそらく切り替えるだろうが、私はこの場合に必要でないと思う。 – paxdiablo

+0

これはmalloc、複数の呼び出しなどで複雑になってしまいます.1つのsnprintfがMAX_PATHサイズのスタック上の配列(100%はそのマクロの移植性についてはわかりません)に関係します。実際にOPはシステムコールを使用する必要がありますシステムコールを使用するように制限されているが、OS –

0

system()に送信する完全なコマンドを含む文字列を作成する必要があります。これはスペースを割り当てます(元のコードでは名前のために行っていないので、 scanfへの呼び出しは失敗する可能性が高い)。あなたのmkdirのようなものの場合は、mkdir &で始まる文字列を作成してディレクトリ名の後に十分なスペースを確保し、scanfを呼び出すときにその文字列内の名前を指し示す場所を指すようにします。後でstrcatやsomesuchをやらなければならないのを防ぎます。そして、これが唯一のものであれば、なぜディレクトリ名を必要とするのでしょう?あなたが好きなもの使用する必要があります

6

:ここ

char name[100]; 
printf("Enter the name of the directory: "); 
if (scanf("%99s", name) == 1) // Not &name 
{ 
    char command[120]; 
    sprintf("%s %s", "mkdir", name); 
    if (system(command) != 0) 
     ...oops... 
} 
+1

'snprintf'を使って、バッファがあふれないようにします。 –

+2

入力を100文字未満に制限し、 'strlen(" mkdir ")'が20未満であるので、これはそのままで安全です。それ以外の状況では、 'snprintf()'が良いでしょう。 –

+0

非常に良い解決策。 –

1

は、それが実装する方法の例です:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 

int main() { 
    char *dirname = NULL; 
    char *cmdline = NULL; 
    size_t len; 
    size_t dirlen = 0; 
    int rv = 0; 

    printf("Enter directory: "); 
    if ((len = getline(&dirname, &dirlen, stdin)) < 0) { 
     perror("getline"); 
     exit(-1); 
    } 

    dirname[len-1] = 0; 
    cmdline = malloc(len+8); 
    snprintf(cmdline, dirlen+8, "mkdir %s", dirname); 
    rv = system(cmdline); 
    free(cmdline); 
    free(dirname); 
    rv = WEXITSTATUS(rv); 
    return rv; 
} 
+1

'dirname'も解放することを忘れないでください。また、['getline()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html)がPOSIX 2008にあり、Linuxおよび* BSDで利用可能であることに注意してくださいMacOS X)、どこでも利用できるわけではありません。 –

関連する問題