2016-02-01 3 views
1

новичок здесь. Я пытаюсь объединить args программы C++ в один массив символов. По какой-то причине, strcat избирательно игнорируя argv[2] в для цикла:C++ strcat игнорирует аргумент?

#include <cstring> 

int main(int argc, char *argv[]) { 

    char *argstr = argv[1]; 

    for(int i=2; i < argc; i++) { 
     argstr = std::strcat(argstr, " "); 
     argstr = std::strcat(argstr, argv[i]); 
    } 

    std::cout << argstr << std::endl; 

    return 0; 
} 

Файл называется qtimer. Таким образом, ожидаемый результат бега:

qtimer asdf 1 2 3

будет:

asdf 1 2 3

, но вместо этого он выводит:

asdf 2 3 (с двумя пробелами после asdf)

Может ли кто-нибудь объяснить, почему это так? Кроме того, есть ли лучший способ сделать это?

+1

'std :: strcat' просто выглядит неправильно! Вы не должны использовать эти функции c мусора, когда у вас есть 'std :: string'. –

ответ

10

Вы добавляете строку, хранящуюся в argv[1], но вы не знаете, что там есть место. Вы переписываете память, которая не принадлежит вам.

Это неопределенное поведение, и все может произойти.

Скорее всего, память, которую вы переписываете, - это память, в которой хранятся другие аргументы, так что к тому моменту, когда вы обращаетесь к ним, они уже повреждены.

Вы должны использовать std::string для операций с строками в C++, это намного лучше и безопаснее.

+1

Для полноты я бы добавил, что для исправления своего кода они могли бы выделить достаточно большое пространство (или точно рассчитать, сколько им потребуется). Например: 'char * argstr = malloc (1024); memset (argstr, 1024, 0); 'для подготовки 1k места для результата. – Sorin

+0

@Sorin Почему динамическое распределение? Для этого вы можете так же легко (еще проще, так как после этого вам не нужно будет освобождать его), создайте массив в стеке 'char buffer [1024] = {0}'. –

+0

1024 недостаточно. Вам нужно округлить вычисление пробела. –