Ошибка сегментации в то время как система () в C - PullRequest
0 голосов
/ 18 декабря 2018

Я хочу использовать скрипт "base64" в linux для кодирования данных и получения их в C. Когда я пытаюсь скомпилировать

char a[200];
strcpy(a, "Hello");
printf("%s", a);

, я получаю вывод

Hello

Теперь, когда я пытаюсь ввести код

char a[200];
strcpy(a, system("echo Hello | base64"));
printf("%s", a);

, я получаю вывод

aGVsbG8K
Segmentation fault

Даже когда я удаляю оператор "printf", я получаю тот же

aGVsbG8K
Segmentation fault

Я хочу сохранить значение вывода

system("echo Hello | base64")

в «а» и не отображать его.Пожалуйста, помогите

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Здесь

strcpy(a, system("echo Hello | base64"));

system() не сохраняет свой результат в массиве, так как system() задача состоит в том, чтобы выполнить command, указанный в аргументе, и распечатать его на консоли, т.е. stdoutбуфер.Со страницы руководства system

system() выполняет команду, указанную в command, вызывая команду /bin/sh -c, и возвращается после ее завершения.

Существует один способ решения проблемы, т. Е. Вместо вывода system() вывода на stdout вы можете перенаправить вывод в файл , а затем прочитать его из файла и печать.Например,

int main(void) {
        close(1); /* stdout file descriptor is avilable now */
        /* create the file if doesn't exist, if exist truncate the content to 0 length */
        int fd = open("data.txt",O_CREAT|O_TRUNC|O_RDWR,0664); /* fd gets assigned with lowest 
                                                  available fd i.e 1 i.e nowonwards stdout output 
                                                  gets rediredcted to file */
        if(fd == -1) {
                /* @TODO error handling */
                return 0;
        }
        system("echo Hello | base64"); /* system output gets stored in file */
        int max_char = lseek(fd,0,2);/* make fd to point to end, get the max no of char */
        char *a = malloc(max_char + 1); /* to avoid buffer overflow or 
                underflow, allocate memory only equal to the max no of char in file */
        if(a == NULL) {
                /* @TODO error handling if malloc fails */
                return 0;
        }
        lseek(fd,0,0);/* from beginning of file */
        int ret = read(fd,a,max_char);/* now read out put of system() from
                                          file as array and print it */
        if(ret == -1) {
                /* @TODO error handling */
                return 0;
        }
        a[ret] = '\0';/* \0 terminated array */
        dup2(0,fd);/*fd 0 duplicated to file descriptor where fd points i.e */
        printf("output : %s \n", a);
        /* to avoid memory leak, free the dynamic memory */
        free(a);
        return 0;
}

Мое вышеупомянутое предложение - временное исправление, и я не буду его рекомендовать, вместо этого используйте [popen], как предложено @chris Turner (http://man7.org/linux/man-pages/man3/popen.3.html), который говорит

Функция popen() открывает процесс путем создания канала, разветвления и вызова оболочки. Поскольку канал по определению является однонаправленным, аргумент типа может указывать только чтение или запись , но не обе; результирующий поток, соответственно, только для чтения или только для записи.

Например,

int main(void) {
        char buf[1024];
        FILE *fp = popen("echo Hello | base64","r");
        printf("%s\n",fgets(buf,sizeof(buf),fp));
        return 0;
}
0 голосов
/ 18 декабря 2018

Если вы прочитаете документацию для system, вы обнаружите, что она не возвращает строку - она ​​определяется как:

int system(const char *command);

Возвращаемое значение - это состояние возврата команды или -1, если есть ошибка.Вы не можете получить выходные данные, используя system - выходные данные команды, которую вы выполняете, перейдут прямо в стандартный вывод.

Чтобы получить выходные данные из другой команды, вы можете использовать что-то вроде popen.

FILE *myfile;
char buffer[1024];

myfile=popen("echo Hello | base64","r");
if(myfile)
  {
  while(fgets(buffer,1024,myfile))
    {
    printf("%s",buffer);
    }

  pclose(myfile);
  }
...