Поскольку передача массива, начинающегося с NULL
(0
), в execv
приводит к распечатке программы LC_MEASUREMENT=de_DE.UTF-8
, я понял, что это должно означать, что argv[3]
ссылается на элемент в процессе environment (LC_MEASUREMENT - одна из переменных среды, используемая для настройки параметров локали в Linux).
execv
Поскольку execv
скопирует текущую среду в новую программу, нам просто нужно изменить среду и поместить строку "Hello World!"
в правильное место перед тем, как звонит execv
. Оказывается, что строка, которая печатается, является той, на которую указывает индекс 2 среды.
Чтобы получить доступ к текущей среде, нам нужно объявить переменную environ
вне main
:
external char **environ;
int main()
{
...
И затем сделать это перед вызовом execv
:
execve
Вместо объявления external char **environ
и изменения текущей среды перед вызовом execv
, мы можем использовать функцию execve
, которая позволяет нам передавать новую массив строк для использования в качестве среды для программы:
char *argv[] = { NULL };
char *envp[] = { "foo", "bar", "Hello World!", NULL };
execve("filepath", argv, envp);
Как показывает приведенный выше фрагмент кода, "Hello World!"
должен находиться в индексе 2
среды, независимо от того, какой метод мы используем. [1 134]
Причина, по которой это работает, заключается в том, что существует стандарт того, как аргументы командной строки и окружение размещаются в памяти процесса при выполнении программы: помещается массив окружений с указателями символов сразу после массива аргументов командной строки.
Поскольку эти массивы завершаются записью NULL, это будет выглядеть следующим образом:
+---------+---------------------------------------+
| Args | Environment |
+---------+---------+---------+---------+---------+
| NULL | envp[0] | envp[1] | envp[2] | NULL |
+---------+---------+---------+---------+---------+
^ ^ ^
| | |
argv[0] argv[1] ... argv[3]
Надеюсь, искусство ASCII поможет вам понять, почему argv[3]
означает то же самое, что и environ[2]
] когда мы выполняем программу следующим образом.
#include <sstream>
#include <string>
std::stringstream ss;
ss << "Hello, world, " << myInt << niceToSeeYouString;
std::string s = ss.str();
Смотрят на эту статью Guru Of The Week от Herb Sutter: Строковые Средства форматирования Фермы Поместья
Ваш код может быть написан как <глоток> 1 глоток>,
s = "Hello world," "nice to see you," "or not."
..., но я сомневаюсь, что это - то, что Вы ищете. В Вашем случае Вы, вероятно, ищете потоки:
std::stringstream ss;
ss << "Hello world, " << 42 << "nice to see you.";
std::string s = ss.str();
<час> <глоток> 1 глоток> " может быть записан как ": Это только работает на строковые литералы. Конкатенация сделана компилятором.
s += "Hello world, " + "nice to see you, " + "or not.";
Те литералы символьного массива не являются станд. C++:: строки - Вы ned для преобразования их:
s += string("Hello world, ") + string("nice to see you, ") + string("or not.");
Для преобразования ints (или любой другой streamable тип) можно использовать повышение lexical_cast или обеспечить собственную функцию:
template <typename T>
string Str( const T & t ) {
ostringstream os;
os << t;
return os.str();
}
можно теперь сказать вещи как:
string s = "The meaning is " + Str( 42 );
Необходимо было бы определить оператор + () для каждого типа данных, который Вы захотите к concenate к строке, все же с тех пор operator< < определяется для большинства типов, необходимо использовать станд.:: stringstream.
Проклятый, избитый на 50 секунд...
повышение:: формат
или станд.:: stringstream
std::stringstream msg;
msg << "Hello world, " << myInt << niceToSeeYouString;
msg.str(); // returns std::string object