1

我是 C 的新手,我尝试制作一个程序,在运行程序时计算作为参数给出的句子中的单词。一个单词是一个或多个字符,由以下任一字符分隔:' '、或。示例:='\n'',''.'./words abc abc2 words

但我不断收到:“ segementation fault(core dumped)”。以下是代码:

int main(char **argv) 
{
    char buf[80];   
    sprintf(buf,"%d words\n",words(argv));
    write(1,buf,strlen(buf));
    return 0;
}

int words(char **argv)
{
    int i=0, sum=0;
    while(argv[i] != '\0')
    {
         if(argv[i] == '.' || argv[i] == ',' || argv[i] == ' ' || argv[i] == '\n')
             sum++;
         i++;
    }

}
4

4 回答 4

1

Argv 是一个**char 或指向字符串数组的指针。您的代码将其视为单个字符串,因此循环遍历指向字符串的指针并对其进行计数。由于这些指针都不是空的,因此程序会继续超出数组的末尾,从而导致段错误。

于 2013-09-28T18:57:14.447 回答
1

如果我没记错的话,参数会自动拆分成单独的字符串。这就是为什么你得到一个指向指针的指针(例如char **,而不是char*)。您只取消引用 argv 数组一次。尝试这个:

while(argv[i] != NULL) {
    i++;
}

其次,您将无法以这种方式检测换行符,因为根据定义,您不能在参数中传递换行符。您可能想要做的是解析来自标准输入的输入并像这样调用您的程序:

echo "abc abc" | ./words

或者

./words < SOME_TEXT_FILE

最后但并非最不重要的一点是,您的 words 函数不返回任何内容,它需要返回 i:

int words(char** argv) {
    //...
    return i;
}

这可能是您的程序段错误的原因,因为返回值words()将为 NULL,然后 sprintf 将尝试取消引用函数的结果。所以整个函数需要看起来像这样:

int words(char** argv) {
    int counter = 0;
    while(char[i] != NULL) {
        int j = 0;
        while(char[i][j] != '\0') {
            if(char[i][j] == '.') { //no need to check for '\n'...
                counter++;
            }
            j++;
        }
        i++;
        counter++;
    }
    return counter;
}
于 2013-09-28T19:01:26.387 回答
1
me.c:2:5: warning: first argument of âmainâ should be âintâ [-Wmain]
me.c:2:5: warning: âmainâ takes only zero or two arguments [-Wmain]
me.c: In function âmainâ:
me.c:4:1: warning: implicit declaration of function âwordsâ [-Wimplicit-function-declaration]
me.c:5:1: warning: implicit declaration of function âwriteâ [-Wimplicit-function-declaration]
me.c:5:1: warning: implicit declaration of function âstrlenâ [-Wimplicit-function-declaration]
me.c:5:13: warning: incompatible implicit declaration of built-in function âstrlenâ [enabled by default]
me.c: In function âwordsâ:
me.c:11:16: warning: comparison between pointer and integer [enabled by default]
me.c:11:33: warning: comparison between pointer and integer [enabled by default]
me.c:11:51: warning: comparison between pointer and integer [enabled by default]
me.c:11:69: warning: comparison between pointer and integer [enabled by default]

gcc -Wall filename.c将产生上述所有警告

这些是代码中的警告。全部避开。然后尝试。

请通过谷歌搜索找到这些的答案

how to use command line arguments

how to declare a function

how to compare strings and how '.' is differ from "."

于 2013-09-28T19:04:20.063 回答
1

1.遍历 argv。
(记住这argv[i]是一个指向 char 的指针,argv[0]保存正在执行的程序的名称,而 argv 的最后一个元素是NULL指针。
2.使用库中的strtok函数string.h来拆分。(每次 strtok 返回非 NULL 值时,都会增加字数)。 通过对命令行参数和 strtok 的一些阅读,您可以轻松地使其与传递的任何参数一起工作。argv[i]" .,\n"


于 2013-09-28T20:54:06.647 回答