Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: С++ Запуск внешних приложений и получение ответа  (Прочитано 2708 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Доброго времени суток, помогите разобраться с сабжем.
Допустим я хочу написать бестолковую программу, которая будет возвращать мне id разных программ по запросу. Например, запускаю, ввожу название необходимого мне приложения и жду ответ.

Вот что у меня получилось:
#include <iostream>
#include <string>

int main()
{
  using std::cout;
  using std::endl;
 
  cout << "Start" << endl;
 
  using std::string;
  string system_ret{0};
  string xyz{0};
 
  using std::cin;
  cout << "Enter query" << endl;
  cin >> xyz;
  cout << "you entered: " << xyz << endl;
 
  string query{"pgrep "};
  query = query + xyz;
 
  system_ret = system(query.c_str());
  cout << "pid is: " << system_ret << endl;
   
  return int();
}

После запуска этой программы появились вопросы, может кто-то сможет мне на них ответить.
Вопрос первый, что лучше и правильнее использовать для таких задач? System, exec, popen, getenv?
Вопрос второй, этой строкой "system_ret = system(query.c_str());" я хотел запустить внешнее приложение и ответ этого приложения записать в system_ret. Но как оказалось, так оно не работает, в этой строке "cout << "pid is: " << system_ret << endl;" system_ret всегда пустой, почему так?

Спасибо за ответ!
ЗЫ: Я только начал изучать ++, так что возможно вопрос и глупый, но все таки ответа в интернете я не нашел.

Оффлайн .ubuntufan

  • Активист
  • *
  • Сообщений: 638
    • Просмотр профиля
System возвращает код возврата процесса а не его PID. Также, тип возвращаемых данных - целое число, а не строка.
http://linux.die.net/man/3/system

А Popen запускает команду и, в отличие от system, возвращает файловый дескриптор, с которым можно взаимодействовать для получения стандартного вывода дочернего процесса / записи в стандартный ввод дочернего процесса.
http://linux.die.net/man/3/popen

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Спасибо, т.е. нужно использовать popen?  System выполнит команду, но ее ответа не вернет.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Может мне кто-то помочь примером? Как мне загнать id   приложения в переменную, а потом вывести эту переменную на экран. Читаю я про этот popen и ничего понять не могу, подходит он мне или я не в ту степь поперся?

Оффлайн Peter_I

  • Старожил
  • *
  • Сообщений: 3271
    • Просмотр профиля
Я думаю, что для этого можно с помощью system запустить pidof.
Пётр.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Мне не нужен pid программы, мне нужно понять как запустить дочернию программу и записать результат ее работы в переменную, которую потом можно использовать дальше походу программы. С id приложения, это я как пример, главное понять логику как это сделать.
Спасибо.

Оффлайн SergeyIT

  • Зануда.
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5744
  • Все по палатам!
    • Просмотр профиля
Где то в книжках читал, но искать надо  :-[
Извините, я все еще учусь

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Я знаю как это сделать через Bash скрипт, это совершенно просто, но как это сделать в с++, никак понять не могу. Все что нахожу в сети, выглядит как-то очень сложно и мудрено. Кроме этого, конкретного ответа на свой вопрос я не нашел, т.е. я даже не могу понять что мне использовать ((

Оффлайн .ubuntufan

  • Активист
  • *
  • Сообщений: 638
    • Просмотр профиля
Цитировать
я даже не могу понять что мне использовать ((

Используйте popen

Оффлайн SergeyIT

  • Зануда.
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5744
  • Все по палатам!
    • Просмотр профиля
Vlad.V, примерно так
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>

int main()
{
using std::cout;
using std::endl;
using std::string;
using std::cin;
  cout << "Start" << endl;
  char buf[20000];
  string prog("");
 
  cout << "Enter command" << endl;
  cin >> prog;
  cout << "you entered: " << prog << endl;
  FILE *fp = popen(prog.c_str(), "r");
  fread(buf, 20000,1,fp);
  cout << "command output:" << endl << buf << endl;
  pclose(fp); 
 
  return int();
}
« Последнее редактирование: 18 Ноября 2014, 14:49:10 от SergeyIT »
Извините, я все еще учусь

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Спасибо! :D Пример работает, теперь буду разбирать его, чтобы понять что и для чего. Но это конечно сложнее чем в простом Баш скрипте сделать "pid=`pgrep skype`". Честно, не думал, что в ++ эта операция займет две строки  :idiot2:
Еще раз спасибо!

Оффлайн SergeyIT

  • Зануда.
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5744
  • Все по палатам!
    • Просмотр профиля
Vlad.V, это не С++, а С (++ для этого не нужен)
Извините, я все еще учусь

Оффлайн .ubuntufan

  • Активист
  • *
  • Сообщений: 638
    • Просмотр профиля
Цитировать
pid=`pgrep skype`"

не путайте ID процесса с выводом команды

Цитировать
Честно, не думал, что в ++ эта операция займет две строки

Там несколько больше по идее. Представленный пример максимально прост и только первые 20к байт вывода считывает. И ++ как уже сказали для этого не нужен:

Код: (c) [Выделить]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define POPEN_BUFFER 4096

int main(void) {
char cmd[201];
char buf[POPEN_BUFFER];

while (1) {
printf("Enter command\n");
scanf("%200[^\n]s", cmd);
if (strcmp(cmd, "exit") == 0) {
break;
}
FILE *fp = popen(cmd, "r");
if (fp) {
while (!feof(fp)) {
if (fgets(buf, POPEN_BUFFER, fp)) {
printf("%s", buf);
}
}
pclose(fp);
}
};

return 0;
}
« Последнее редактирование: 18 Ноября 2014, 16:20:17 от .ubuntufan »

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Vlad.V, это не С++, а С (++ для этого не нужен)

Насколько я знаю, USING, COUT и т.д. в С отсутствуют. А вот <stdlib.h> и <stdio.h>, согласен СИшные. Но Ваш пример идеально работает и без этих хедеров, используя только <iostream> и <string>, так что как по мне стиль все больше похож на ++ и конечно хвала обратной совместимости)))
Но так как я еще только учусь, возможно, я не прав.

Оффлайн SergeyIT

  • Зануда.
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5744
  • Все по палатам!
    • Просмотр профиля
.ubuntufan, а выход из цикла где, а закрыть райп где? По ctrl+C некрасиво будет ;)
Извините, я все еще учусь

 

Страница сгенерирована за 0.018 секунд. Запросов: 21.