1

Red Hat Linuxでcatコマンドをシミュレートしようとしています。プログラムを実行すると、セグメンテーション違反が発生します。

例えば:

./a.out a > b

aこんにちはが含まれています。hello が にコピーされることを期待していbます。

私のコードは次のとおりです。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char *argv[])
{
    int f, fd, r;
    char buf[100];

    if (argc < 2)
    {
        printf("Error");
        return 0;
    }
    else
    {
        if (!strcmp(argv[2],">"))
        {
            f = open(argv[1],0,00777);

            if (f == -1)
                printf("no file");
            else
            {
                fd = creat(argv[3],00777);
                while( (r = read(f,buf,50)) > 0)
                    write(fd, buf, r);
            }
        }
    }
    return 0;
}

セグメンテーション エラーが発生するのはなぜですか?

同じ方法でファイルを開いて作成する同様のプログラムがあり、そのプログラムが実行されていますが、これによりセグメンテーション違反が発生しています。

4

3 に答える 3

6

これはおそらく、リダイレクトがプログラムではなくシェルによって処理されるためargv[2]でありNULLargv[3]存在しないためです。

ただし、デバッガーを使用して、実際に何が起こっているかを確認する必要があります。そして、適切なエラーチェックを追加します。

于 2013-04-30T16:22:41.570 に答える
4

ここがなくても生きgdbていけますが、構造化された方法で問題を解決する必要があります。

  • 何事も当たり前だと思わないでください。たとえば、プログラムを として呼び出したとしても、それが想定どおりに見えるprogram > fileと仮定しないでください。それぞれを出力して確認してください。argv

    printf("argc: %d\n", argc);
    printf("argv[0]: %s\n", argv[0]);
    printf("argv[1]: %s\n", argv[1]);
    printf("argv[2]: %s\n", argv[2]);
    printf("argv[3]: %s\n", argv[3]);
    // the se can be expressed better with a for loop - but I'll leave that as an exercise for you
    
  • 確認したことだけを当然のことと考えてください。それがわかっている場合は、および/または にargc >= 2アクセスしないでください。argv[2]argv[3]

  • 言わないで

    if(argc<2)
    {
        printf("Error");
        return 0;
    }
    

    しかし

    if(argc<2) // according to the point before, better y3 or <4
    {
        printf("Too few command line arguments");
        return 1; // not 0; 0 would mean success
    }
    
于 2013-04-30T16:36:48.580 に答える
1

Joachim Pileborg の答えは明らかに正しいです。プログラムを次のように実行してみてください。

./a.out a \> b

シェルが ">" をリダイレクトとして解釈しないようにします。

于 2013-04-30T18:09:36.200 に答える