ВОПРОС · Q&A

Проблема в С,scanf,fgets(gcc-9.3.0-Debian, OC:Kali Linux kali-rolling,kernel:5.4.0-kali4-amd64#1SMP Debian 5.4.19-1kali1(2020-02-17)x86_64GNU/Linux.)

4 ответов 2,5 тыс.
AI-выжимка обсуждения скоро

Краткие тезисы обсуждения со ссылками на ключевые ответы появятся здесь.

Автор вопроса
пишу код на C. Приходится использовать fgets(), т.к. scanf() считывает символы до пробела, что не допустимо.(Google - один годный вариант, нос циклом, что не нужно. break - пропуск (или игнорирование) цикла. Расширение файла измените на .c. .c не поддерживается.
C:
#include <stdio.h>
#include <stdlib.h> // для работы с системой(system(""); используется для исполнения системных комманд(да, я знаю, что туда можно вставить kill -9 -1)))))

int main() {
printf("Отсутствие вывода абсолютно нормально\n");
printf("1 - Расшифровка\n2 - шифровка\n");
int a; // ввел переменную раньше if'а решил не засовывать scanf в if))
scanf("%d", &a);
do { // пришлось поставить, чтобы использовать break; иначе ошибка: break вне цикла.((
if (a == 2) {
FILE * fo; // вводим указатель на файл
fo = fopen("message.txt", "w"); // открытие или создание файла message.txt с правами на запись. Если файл существует, содержимое стирается
char d[1024]; // этот размер быбран не случайно, не измень без необходимости))
fflush(stdin);
fflush(stdout);
fgets(d, 1000, stdin); // как сделать, чтобы шел ввод строки не посимвольно, а сразу, с пробелами? игнорируется по неизвестной причине
fputs(d, fo); //вывод строки в файл.
fclose(fo);
system("openssl rsautl -encrypt -inkey keys/publickey.pem -pubin -in message.txt -out message.txt.enc;"); // шифровка сообщения
printf("Текст и сохраненное сообщение в файлах message.txt и message.txt.enc\nХотите удалить незашифрованный текст сообщения?\n1 - да.\n2 - нет\n");
int b;
if (scanf("%d", &b) == 1) {
    fflush(stdin);
system("rm -R message.txt"); // удаление файла с незашифрованным текстом
break;
}
if (scanf("%d", &b) == 2) {
break; // было лень использовать continue)) Надо было, чтобы цикл "сломался" и программа завершила свою работу при указанном выше пункте(2)
}
break; // "поломка" цикла второго пункта главного меню
}
if (a == 1) {
    fflush(stdin);
system("openssl rsautl -decrypt -inkey keys/privatekey.pem -in message.txt.enc -out message_decrypted.txt;"); // расшифровка
printf("Текст сообщения: \n");
printf("\n");
system("cat message_decrypted.txt");
printf("\n");
printf("\n");
printf("Расшифрованное сообщение в файле message_decrypted.txt\nУдалить зашифрованный файл?\n1 - да.\n2 - нет\n");
int g;
if (scanf ("%d", &g) == 1) {
system("rm -R message.txt.enc");
break;
}
if (scanf ("%d", &g) == 2) break;
}
break; // поломка do
}
while (1);
return 0;
}
 
scanf читает из потока, по заданному формату в твоем случае scanf("%d").
fgets - читает из потока, до тех пор, пока не встретит в потоке '\n'(перенос строки).
И получается забавная ситуация:
  1. Пользователь вводит 2 для шифрования и нажимет Enter;
  2. В потоки stdin имеем '2\n'
  3. scanf("%d", &a) считывает из потока stdin десятичное число.
  4. В потоке stdin имеем '\n'
  5. fgets(d, 1000, stdin) читает из потока '\n' и останавливается
  6. В потоке stdin имеем ''
Лечится добавление getc(stdin) после scanf("%d", &a)
C:
#include <stdio.h>                                                                                                                                                                
#include <stdlib.h>                                                                                                                                                               
                                                                                                                                                                                  
#define BUF_SIZE 1024                                                                                                                                                             
                                                                                                                                                                                  
void encrypt() {                                                                                                                                                                  
  FILE * fo;                                                                                                                                                                      
  fo = fopen("message.txt", "w");                                                                                                                                                 
  char d[BUF_SIZE];                                                                                                                                                               
  fflush(stdin);                                                                                                                                                                  
                                                                                                                                                                                  
  printf("Введите текст:\n");                                                                                                                                                     
  fgets(d, BUF_SIZE, stdin);                                                                                                                                                      
  fputs(d, fo);                                                                                                                                                                   
  fclose(fo);                                                                                                                                                                     

  system("openssl rsautl -encrypt -inkey keys/publickey.pem -pubin -in message.txt -out message.txt.enc;"); 
  printf("Текст и сохраненное сообщение в файлах message.txt и message.txt.enc\nХотите удалить незашифрованный текст сообщения?\n1 - да.\n2 - нет\n");

  int b;
  scanf("%d", &b);
  if (b == 1) {
    fflush(stdin);
    system("rm -R message.txt"); 
    return;
  }

  return;
}

void decrypt() 
{
  fflush(stdin);
  system("openssl rsautl -decrypt -inkey keys/privkey.pem -in message.txt.enc -out message_decrypted.txt;"); 
  printf("Текст сообщения: \n\n");
  system("cat message_decrypted.txt");
  printf("\n\nРасшифрованное сообщение в файле message_decrypted.txt\nУдалить зашифрованный файл?\n1 - да.\n2 - нет\n");
  int g;
  scanf ("%d", &g);
  if (g == 1) {
    system("rm -R message.txt.enc");
    return;
  }
}

int main() {
  printf("Отсутствие вывода абсолютно нормально\n");
  printf("1 - Расшифровка\n2 - шифровка\n");
  int a; 
  scanf("%d", &a);
  getc(stdin);

  switch (a) {
    case 2: encrypt(); break;
    case 1: decrypt(); break;
    default: break;
  }
  return 0;
}
 
scanf читает из потока, по заданному формату в твоем случае scanf("%d").
fgets - читает из потока, до тех пор, пока не встретит в потоке '\n'(перенос строки).
И получается забавная ситуация:
  1. Пользователь вводит 2 для шифрования и нажимет Enter;
  2. В потоки stdin имеем '2\n'
  3. scanf("%d", &a) считывает из потока stdin десятичное число.
  4. В потоке stdin имеем '\n'
  5. fgets(d, 1000, stdin) читает из потока '\n' и останавливается
  6. В потоке stdin имеем ''
Лечится добавление getc(stdin) после scanf("%d", &a)
C:
#include <stdio.h>                                                                                                                                                               
#include <stdlib.h>                                                                                                                                                              
                                                                                                                                                                                 
#define BUF_SIZE 1024                                                                                                                                                            
                                                                                                                                                                                 
void encrypt() {                                                                                                                                                                 
  FILE * fo;                                                                                                                                                                     
  fo = fopen("message.txt", "w");                                                                                                                                                
  char d[BUF_SIZE];                                                                                                                                                              
  fflush(stdin);                                                                                                                                                                 
                                                                                                                                                                                 
  printf("Введите текст:\n");                                                                                                                                                    
  fgets(d, BUF_SIZE, stdin);                                                                                                                                                     
  fputs(d, fo);                                                                                                                                                                  
  fclose(fo);                                                                                                                                                                    

  system("openssl rsautl -encrypt -inkey keys/publickey.pem -pubin -in message.txt -out message.txt.enc;");
  printf("Текст и сохраненное сообщение в файлах message.txt и message.txt.enc\nХотите удалить незашифрованный текст сообщения?\n1 - да.\n2 - нет\n");

  int b;
  scanf("%d", &b);
  if (b == 1) {
    fflush(stdin);
    system("rm -R message.txt");
    return;
  }

  return;
}

void decrypt()
{
  fflush(stdin);
  system("openssl rsautl -decrypt -inkey keys/privkey.pem -in message.txt.enc -out message_decrypted.txt;");
  printf("Текст сообщения: \n\n");
  system("cat message_decrypted.txt");
  printf("\n\nРасшифрованное сообщение в файле message_decrypted.txt\nУдалить зашифрованный файл?\n1 - да.\n2 - нет\n");
  int g;
  scanf ("%d", &g);
  if (g == 1) {
    system("rm -R message.txt.enc");
    return;
  }
}

int main() {
  printf("Отсутствие вывода абсолютно нормально\n");
  printf("1 - Расшифровка\n2 - шифровка\n");
  int a;
  scanf("%d", &a);
  getc(stdin);

  switch (a) {
    case 2: encrypt(); break;
    case 1: decrypt(); break;
    default: break;
  }
  return 0;
}
Спасибо, помог, правда я не понял, зачем case и define. Хотя я вообще не знаю функции case и switch. Я понял, что Вы перенесли части на функции encrypt() и decrypt(). Вроде, функции можно запустить их упоминанием, разве ,что смущает, так это case, т.к. void'oм были введены вышеупомянутые функции.

понял значение case, объяснения не нужны))
 
Спасибо, некоторые "комманды" я могу понять сходу. А книгу я возьму на заметку.