2010-03-31 52 views
2
#include<stdio.h> 
#include<zlib.h> 
#include<unistd.h> 
#include<string.h> 


int main(int argc, char *argv[]) 
{ 
    char *path=NULL; 
    size_t size; 
    int index ; 
    printf("\nArgument count is = %d", argc); 
    printf ("\nThe 0th argument to the file is %s", argv[0]); 
    path = getcwd(path, size); 
    printf("\nThe current working directory is = %s", path); 
    if (argc <= 1) 
    { 
     printf("\nUsage: ./output filename1 filename2 ..."); 
    } 
    else if (argc > 1) 
    { 
     for (index = 1; index <= argc;index++) 
     { 
      printf("\n File name entered is = %s", argv[index]); 
      strcat(path,argv[index]); 
      printf("\n The complete path of the file name is = %s", path); 
     } 
    } 
    return 0; 
} 

在上面的代码,这里是我得到的运行代码时的输出:段错误读取时的命令行参数

$ ./output test.txt 

Argument count is = 2 
The 0th argument to the file is ./output 
The current working directory is = /home/welcomeuser 
File name entered is = test.txt 
The complete path of the file name is = /home/welcomeusertest.txt 
Segmentation fault (core dumped) 

谁能请我明白为什么我得到一个核心转储错误?

回答

9

您将通过说index <= argcargv结束。那应该是index < argc。请记住,阵列索引从,比阵列的长度小

(你是正确的,在1开始,因为argv[0]是程序名称。)

3

getcwd()分配一个大小等于sizepath的缓冲区。您没有初始化size变量。将其设置得足够大以容纳整个路径和名称,并且这应该起作用。如果缓冲区不够大,则strcat()将写入缓冲区末尾,覆盖堆栈上的其他值(可能包括函数返回指针,这会在return上导致段错误)。

此外,getcwd()使用malloc()来分配您分配给path的缓冲区。当你完成这个缓冲区时,这将是很好的free()。尽管在程序结束时这不是必须的 - 因为系统无论如何都会回收内存。

你的代码中也有一些逻辑错误。首先,argv阵列指数范围从0到argc -1。您的for环路退出条件使您读取argv数组末尾的一个元素。

请注意,strcat()会将每个迭代的新参数添加到上一个迭代的结果中。这意味着,调用/home$ ./output foo bar baz最终会:

The complete path of the file name is = /home/foo 
The complete path of the file name is = /home/foobar 
The complete path of the file name is = /home/foobarbaz 

这可能不是你想要的:)。 (省略了不相关的输出行)。

+1

也许初始化'size'会是另一个好主意。 – 2010-03-31 22:26:59

+0

getcwd()将向malloc缓冲区传递一个空指针。 – 2010-03-31 22:28:15

+0

@ honk: 哈哈,真的:)。 – slacker 2010-03-31 22:29:03

4

strcat无效。它试图将数据连接到由C运行库lib调用返回的缓冲区。你需要使用你自己的缓冲区。而且你需要以你使用它的方式在getcwd()返回的缓冲区上使用free()(传入NULL使它分配内存)。

+0

嗨马克, 请您详细说明您的观察。我是C上的字符串操作和文件操作的新手。任何能帮助我理解你指向的资源都将受到高度赞赏。 Regards, darkie – 2010-03-31 22:36:47

+0

@darkie:我正在查看linux机器上的手册页,它表明如果给定的缓冲区为NULL,getcwd会用malloc分配一个缓冲区。 (http://linux.die.net/man/3/getcwd)。但它似乎依赖于版本。但是,返回的缓冲区可能不够长,无法追加新数据。 strcat会将新数据添加到该缓冲区并覆盖分配的空间。 – 2010-03-31 22:49:22

1

strcat(path,argv[index])正在将数据添加到不足以容纳附加数据的缓冲区。

您应该传入一个size值,以确保缓冲区足够大。您还没有初始化size,所以您真的不知道将返回的缓冲区大小(所有这些都假设您使用的是GNU libc版本getcwd(),如果您传入NULL,它将分配缓冲区)。

+0

显然你的代码中至少有2个bug。 RichieHindle,Donal研究员和Charles Bailey发现了另一个严重问题。 – 2010-03-31 22:34:32

+0

嗨迈克尔, 我是新来的C和字符串和文件操作。任何良好的资源,以帮助我了解需要在这里做什么将高度赞赏。 Regards, darkie – 2010-03-31 22:38:27

+0

K&R C书仍然是黄金标准。 – 2010-03-31 22:44:11

1

你阅读过的argv结束。不要这样做。停止在argc-1'th的论点。

2

尽管关于strcat的回答是有效的,但考虑到程序崩溃的问题是空指针顺从,因为您使用的是<= argc而不是< argc

在C中,argv[argc]是一个NULL指针。