0

こんにちは、すべての質問で申し訳ありませんが、このコードを実行すると、ターミナル ウィンドウに「セグメンテーション エラー (コア ダンプ)」が表示されます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int usage (void) {
    printf("Usage: head <file>\n");
    printf("   Or: head <file> -n <number of characters>\n");
    printf("   Or: head -n <number of characters> <file>\n"); 
    return -1;
}

int main (int argc,char **argv) {
    if ((argc != 2) && (argc != 4)) return usage();

    char *fileName = argv[1];
    int lineCount = 10;
    FILE *src;

    if ((argc == 4) && (strcmp(argv[1], "-n" != 0))){
        fileName = argv[1];
        lineCount = argv[3]; 
        puts("-n in last position");
    }else{
        fileName = argv[3];
        lineCount = argv[1];
        puts("-n in first position");
    }

    if((src = fopen(fileName, "r")) == NULL){
        puts("Can't open input file.");
        exit(-1);
    }
}

fopen 関数によるものだと確信していますが、なぜこれが起こっているのか正確にはわかりません。

4

4 に答える 4

6

argc==2 の場合、すぐに argv[3] にアクセスするように見えます。それは痛いです。

于 2012-09-11T02:31:44.723 に答える
5

最初にいくつか間違っていることがあります - 比較は関数内にあります

strcmp(argv[1], "-n" != 0)

char * を int に割り当てています

lineCount = argv[3];

そしてここ

lineCount = argv[1];

ここに私が得るコンパイルエラーがあります

[adrian@iceweasel ~]$ gcc -Wall -ansi -pedantic uu.c
uu.c: In function ‘main’:
uu.c:15: warning: ISO C90 forbids mixed declarations and code
uu.c:19: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast
/usr/include/string.h:143: note: expected ‘const char *’ but argument is of type ‘int’
uu.c:21: warning: assignment makes integer from pointer without a cast
uu.c:25: warning: assignment makes integer from pointer without a cast
uu.c:33: warning: control reaches end of non-void function
于 2012-09-11T02:32:00.563 に答える
1

間違った場所に閉じ括弧の1つがあります:

(strcmp (argv[1], "-n" != 0))

する必要があります:

(strcmp (argv[1], "-n") != 0)

ただし、それが修正されたとしても、引数の処理はまだ完全には正しくありません。

あなたの前の質問では、それhead -n COUNT FILEは可能性ではありませんでした、それは議論のチェックをかなり簡単にしました。

-n count「フローティング」セクションを許可するために、従う必要のあるロジックは次のとおりです。

int linecount
char *filename = NULL

if argc == 2:
    linecount = 10
    filename = argv[1]
else:
    if argc == 4:
        if argv[1] == "-n":
            linecount = argv[2]
            filename = argv[3]
        else:
            if argv[2] == "-n":
                linecount = argv[3]
                filename = argv[1]

if filename = NULL:
    generate some error

基本的に、2つの引数のバージョンを最初にキャッチします。4引数バージョンの場合は、「-n」がどこにあるかを検出するため、どの引数がどの値であるかをインテリジェントに判断できます。

ご覧のとおり、それはあなたが持っているものではありません(あなたのコードは行数を探しますが、決してargv[1]そうではありません)。ガイドとして次のようなものを使用する必要があります。

argc  argv[0]  argv[1]  argv[2]  argv[3]
----  -------  -------  -------  -------
   2  head     <file>
   4  head     <file>   -n       <count>
   4  head     -n       <count>  <file>

それを参照すると、さまざまな状況に対応するコードを簡単に記述できるはずです。

もちろん、私の擬似コードをCに戻す必要があります(文字列strcmpの代わりに使用し、文字列のlinecount引数を整数に変換するため==に使用することを確認してください)が、それが従うべき基本的なフローです。atoi/strtol

于 2012-09-11T02:42:06.400 に答える
0

getopt()機能を使用してもよろしいですか?Linux では、getopt()関数は、(環境変数が設定され-nていない限り) どちらの場所でもオプションを処理します。POSIXLY_CORRECTそれはあなたの人生を楽にするでしょう:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int numLines = 10;
    char *fileName = 0;
    int opt;

    while ((opt = getopt(argc, argv, "n:")) != -1)
    {
        switch (opt)
        {
        case 'n':
            numLines = atoi(optarg);  /* Could check for positive answer */
            break;
        default:
            usage();  /* Assuming usage() does not return */
            break;
        }
    }

    if (optind != argc - 1)  /* Insist on one filename argument */
        usage();

    fileName = argv[optind];

    ...open file and process it...

    return(0);
}

ファイルの代わりに標準入力を処理する方が簡単であることに注意してください。もちろん、ループ後の条件は調整する必要があります。-?また、ヘルプなど-hのオプションを簡単に追加することもできます。

于 2012-09-11T02:49:08.967 に答える