2010-03-31 2 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

Вы собираетесь в конец argv, сказав: index <= argc. Это должно быть index < argc. Помните, что индексы массива идут от ноль до один меньше длины массива.

(Вы правильно начать в 1, потому что argv[0] это название программы.)

3

getcwd() выделяет буфер для path размером, равным size. Вы не инициализировали переменную size. Установите его достаточно большим, чтобы удерживать весь путь и имя, и это должно работать. Если буфер недостаточно велик, то strcat() будет писать за конец буфера, перезаписывая другие значения в стеке (возможно, включая указатель возврата функции, что вызовет segfault на return).

Также getcwd() использует malloc(), чтобы выделить буфер, который вы назначаете path. Было бы неплохо, если бы этот буфера был сделан, когда вы закончите с этим. Хотя это совсем не обязательно в конце программы - так как система все равно вернет память.

В коде есть некоторые логические ошибки. Во-первых, индексы массива 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' была бы еще одной хорошей идеей. –

+0

getcwd() будет malloc-буфером, если вы передадите ему нулевой указатель. –

+0

@honk: Hah, true :). – slacker

4

Недействительный strcat. Он пытается объединить данные в буфер, возвращенный вызовом lib runtime. Вам нужно использовать собственный буфер. И вам нужно использовать free() в буфере, возвращенном getcwd() в том виде, в котором вы его используете (передача в NULL приводит к тому, что он выделяет память).

+0

Hi Mark, Не могли бы вы рассказать о своем наблюдении. Я новичок в работе над строковыми операциями и файловыми операциями на C. Любой хороший ресурс, который поможет мне понять, что вы указали, будет высоко оценен. С уважением, darkie –

+0

@ darkie: Я смотрел страницу руководства в окне linux, и это указывает, что getcwd выделяет буфер с malloc, если данный буфер равен NULL. (Http://linux.die.net/man/3/getcwd). Однако, похоже, он зависит от версии. Однако возвращаемый буфер, вероятно, не будет достаточно длинным для добавления новых данных. Strcat добавит новые данные в этот буфер и перезапишет выделенное пространство. –

1

strcat(path,argv[index]) добавляет данные в буфер, который недостаточно велик для хранения дополнительных данных.

Вы должны передать значение size, которое обеспечит достаточный объем буфера. Вы также не инициализируете size, поэтому вы действительно не знаете, какой буфер размера будет возвращен (все это предполагает, что вы используете версию GNU libc getcwd(), которая будет выделять буфер, если вы пройдете в NULL).

+0

По-видимому, в вашем коде есть как минимум 2 ошибки. RichieHindle, Donal Fellows и Charles Bailey обнаружили еще одну серьезную проблему. –

+0

Hi Michael, Я новичок в строковых и файловых операциях в C. Любой хороший ресурс, который поможет мне понять, что нужно сделать здесь, будет высоко оценен. С уважением, darkie –

+0

Книга K & R C по-прежнему является золотым стандартом. –

1

Вы читаете с конца argv. Не делай этого. Остановитесь на аргументе argc-1.

2

Несмотря на то, что ответы о strcat действительны, с учетом того, в какой момент ваша программа терпит крах, проблема является признаком NULL-указателя, поскольку вы используете <= argc, а не < argc.

В C argv[argc] является указателем NULL.

Смежные вопросы