C中的多个条件检查

问题描述 投票:-1回答:3

我制作了一个shell脚本来备份,查看和恢复Linux系统中已安装的软件包。该脚本如下所示:

#!bin/bash

echo ""
read -p "You are about to backup installed packages. Continue (y/n)?:" CONT
echo ""
if [ "$CONT" = "y" ]; then
  eval sudo pacman -Qqe | grep -vx "$(pacman -Qqm)" > packages;
else
  echo "Ok. I got you, I won't backup";
fi

    read -p "View list? (y/n):?" CONT
if [ "$CONT" = "y" ]; then
    eval xargs -a packages ;
else
    echo "Preparing to restore"
fi
echo ""
read -p "So restore list contents (y/n):?" CONT
echo ""
if [ "$CONT" = "y" ]; then
    eval sudo xargs -a packages pacman -S --needed ;
else
    echo "Ok. No packages restored!";
fi

此脚本创建一个文本文件,其中包含系统中安装的所有软件包名称,然后提示用户查看列表,最后允许他恢复备份列表中包含的软件包。然后,我决定使用C来做同样的事情。我创建了一个如下程序:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main() {
char ans[2];
char command[100];
printf("\nYou are about to backup installed packages. Continue (Y/N)?:");
scanf("%1s", ans);
if (strcmp(ans, "Y")==0) {
    strcpy(command, "sudo pacman -Qqe | grep -vx '$(pacman -Qqm)' > packages");
    system(command);
    printf("\nBackup done! \n");
  }
else {
    printf ("\nGot you, I won't backup \n");
  }
}

但是,如果用户想要备份列表,则此代码只能为用户提供单一选择。由于while循环,如果我尝试在现有的while循环中添加另一个条件,我会陷入陷阱。

我需要一些帮助才能完成以下条件。如何为用户提供其他选择,例如:

1)查看备份列表? 2)恢复备份列表包含的软件包?

一个例子将非常有用:))

c linux bash unix sh
3个回答
0
投票

正确的是

if(scanf("%1s",ans)!=1){
   // error handle
}

这将使您在strcmp函数中正确使用它。

或者你可以做到这一点

if(scanf("%c",&ans[0])!=1){
   // error handle
}
ans[1]=0;

然后你可以在strcmp中使用它,或者只是你可以使用它

if(ans[0]=='Y'){
   ...
}

检查scanf的返回值以了解scanf呼叫是否成功。

而不是strcpy使用sprintf或类似,以便你不会遇到缓冲区溢出。在这里你知道长度,但在许多情况下你不会 - 这对sprintf来说是好的和安全的。

如果在编译器中启用警告,则会看到类型不匹配警告。就像是

format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[2]' [-Wformat=]
     scanf("%s",&ans);
     ^

尝试使用-Wall -Werror标志编译代码。


0
投票

我最终做了这个:)

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main() {
    char ans[2];
    char command[100];
    printf("\nYou are about to backup installed packages. Continue? (Y/N):");
    scanf("%1s", ans);
    if(ans[0]=='Y'|| ans[0]=='y') {
        sprintf(command, "sudo pacman -Qqe | grep -vx '$(pacman -Qqm)' > packages");
        system(command);
        printf("\nBackup done! \n");
    }
    if(ans[0]=='N'|| ans[0]=='n') {
        printf ("\nOk. Got you, I won't backup \n");
        exit(EXIT_SUCCESS);     
    }

    printf ("\nView list? (Y/N):\n");
    scanf("%1s", ans);
    if(ans[0]=='Y'|| ans[0]=='y') {
    sprintf(command, "xargs -a packages");
        system(command);
        printf("\n");
    }
    else {
        printf ("\nPreparing to restore \n");
    }
    printf ("So restore list contents? (Y/N):");
    scanf("%1s", ans);
    if(ans[0]=='Y' || ans[0]=='y'){
        sprintf(command, "sudo xargs -a packages pacman -S --needed");
        system(command);
        }
        else {
            printf ("\nOk. No packages restored!\n");
        }
}

0
投票

由于while循环,如果我尝试在现有的while循环中添加另一个条件,我会陷入陷阱。

我不完全得到你在那里说的话(我可以看到那里没有while循环),但这里是我的答案。您可以使用类似的if-else结构来提示用户列出备份并从中还原。您的最终计划将如下所示:

#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
int main() {
    char ans;    //You need only a char variable, not an array

    printf("\nYou are about to backup installed packages. Continue (Y/N)?:");
    scanf(" %c", &ans);
    if (toupper(ans) == 'Y') {
        system("sudo pacman -Qqe | grep -vx '$(pacman -Qqm)' > packages");
        printf("\nBackup done! \n");
    }
    else
        printf ("\nGot you, I won't backup \n");

    printf("\nView list? (y/n) ");
    scanf(" %c",&ans);
    if(toupper(ans) == 'Y')
        system("xargs -a packages");

    printf("\nSo restore listed contents? (y/n) ");
    scanf(" %c",&ans);
    if(toupper(ans) == 'Y')
        system("sudo xargs -a packages pacman -S --needed");
    else
        printf("\nOK, no packages restored.");
}

否则,您可以使用基于菜单的方法来解决问题:

#include<stdio.h>
#include<stdlib.h>

void backup(){
    system("sudo pacman -Qqe | grep -vx \"$(pacman -Qqm)\" > packages");
    printf("\nBackup done!");
}

void list(){
    printf("\nHere comes the listing:\n");
    system("xargs -a packages");
}

void restore(){
    system("sudo xargs -a packages pacman -S --needed");
    printf("\nRestore done!");
}

int main(){
    char choice;
    do{
        printf("\nSelect any action from the following:\n\
        1. Backup packages\n\
        2. List packages\n\
        3. Restore packages\n\
        4. Exit\
    >>> ");
        scanf(" %c",&choice);
        switch(choice){
            case '1': backup();
                  break;
            case '2': list();
                  break;
            case '3': restore();
                  break;
            default : printf("\nIllegal choice!");
        }
    }while(choice!='4');    
    return 0;
}

编辑:修复scanf()错误,请参阅:https://gsamaras.wordpress.com/code/caution-when-reading-char-with-scanf-c/

© www.soinside.com 2019 - 2024. All rights reserved.