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

您在错误的位置有一个右括号:

(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

它基本上首先捕获了两个参数的版本。如果它是四参数版本,它会找出“-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而不是==用于字符串,并确保atoi/strtol用于将字符串 linecount 参数转换为整数),但这是您应该遵循的基本流程。

于 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 回答