简体   繁体   English

C程序不执行主程序外部的功能

[英]the C program does not execute the function outside the main

If I execute the exec() function in another C program as a main function it works perfectly, while if I put it as a function called in the main menu it gives me some warning and the function does not run. 如果我在另一个C程序中将exec()函数作为主要函数执行,则它运行良好,而如果我将它作为在主菜单中调用的函数放置,则会给我一些警告,并且该函数无法运行。

My code: 我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */

int exec (void) {

        char array[100];
        char character;
        int i = 0;
        char* point;
        int j = 0;

        printf ("Digita una stringa");
        printf ("\n");
        do {
            character = getchar();
            array[i] = character;
            i++;
        }
        while (character != '\n');
        array[i-1] = '\0';
        i = 0;

        char* string[100];

        char *word = strtok(array, " .");
        j = 0;
        while (word != NULL) {
            printf("%s\n", word);
            string[j++] = word; // Increment j
            word = strtok(NULL, " .");
        }
        string[j] = NULL; // Make sure the array is NULL term

        printf ("\n");  

    pid_t  pid;
    pid = fork();
    int status;

    if (pid == -1) {
        perror("");
    }else if (pid == 0) {
        execvp(string[0], string);     /* execute the command  */
                fprintf(stderr, "Failed to exec");  
                exit(1);
            }
    else {

        //.. wait until the child ends
        waitpid(-1, &status, 0);
      }

return;
}

int read_input (void) {
    int choice;
    printf("Seleziona una voce dal menu");
    do {    
        printf("\n");
        scanf ("%i", &choice);
        if (choice > 8 || choice < 1)
            printf ("Attenzione, inserisci un valore contemplato dal menu");
    }
    while ( choice > 8 || choice < 1);

return choice;
}

void main (int argc, char *argv[]) {

    printf ("------------------------\n");
    printf ("          MENU         \n");
    printf ("------------------------\n");
    printf ("  \n");
    printf ("1) Esecuzione in foreground di un processo\n");
    printf ("2) Ctrl -C\n");
    printf ("3) Exit\n");
    printf ("4) Background\n");
    printf ("5) Pipe\n");
    printf ("6) Jobs\n");
    printf ("7) fg\n");
    printf ("8) kill\n");
    int menu = read_input();
    switch (menu) {

        case '1' :  
                exec ();
                break; 
        case '2' :
                //ctrl();
                break;
        case '3' :
                //exit_();
                break; 
        case '4' : 
                //background();
                break;
        case '5' :
                //pipe();
                break;
        case '6' : 
                //jobs();
                break;
        case '7' : 
                //fg();
                break;
        case '8' : 
                //kill();
                break;
    }
}

this is the warning: 这是警告:

elaborato.c:31:16: warning: initialization makes pointer from integer without a cast [enabled by default] char *word = strtok(array, " ."); 

Regarding the problem related to input, 关于与输入有关的问题,

do {    
    printf("\n");
    scanf ("%i", &choice);
    if (choice > 8 || choice < 1)
        printf ("Attenzione, inserisci un valore contemplato dal menu");
}
while ( choice > 8 || choice < 1);

Once you type an integer and press enter, the scanf() consumes the number and a newline is left in stdin. 键入整数并按Enter键后, scanf()将使用该数字,并在stdin中保留换行符。 Next time the loop goes around (assuming input <1 or >8 or something else) scanf gets that newline and it goes on. 下次循环循环时(假设输入<1或> 8或其他),scanf获取该换行符并继续。 add a getchar() after the scanf() . scanf()之后添加一个getchar() scanf()

The answer is in the warnings, you should move them from the comment into the question. 答案在警告中,您应该将其从注释移到问题中。

elaborato.c:31:16: warning: initialization makes pointer from integer without a cast [enabled by default] char *word = strtok(array, " ."); 

That means that word , which is a char pointer is being initialized from an integer. 这意味着从整数初始化为char指针的word Therefore, it seems strtok() is returning an integer... that doesn't sound right. 因此,似乎strtok()返回的是整数……听起来不太正确。

From the strtok() man page: strtok()手册页中:

#include <string.h> 

char *strtok(char *str, const char *delim);

char *strtok_r(char *str, const char *delim, char **saveptr);

That seems right, it returns a char * .... but it also says it's declared in <string.h> ... which you aren't including. 看起来很正确,它返回一个char * ....但它还说它是在<string.h> ...中声明的,您不包括在内。 Since it's not defined, the compiler assumes it as int strtok() . 由于未定义,因此编译器将其假定为int strtok()

Fix: add the #include <string.h> line. 修复:添加#include <string.h>行。

The problem you are seeing is that of scanf getting skipped. 您看到的问题是scanf被跳过了。

For more details you can refer here 有关更多详细信息,请参阅此处

The call to scanf() after the printf consumes the new-line character and continues without the user having to enter anything. printf之后对scanf()的调用消耗了换行符,并且继续进行而无需用户输入任何内容。

It reads the very next character from standard in, which is probably a newline character and thus not prompting you for any input. 它从standard in读取下一个字符,这可能是换行符,因此不会提示您输入任何内容。

I'm too tired to comment on the entire code (it is really bad), so I'll just write about the issue in question and how trivially it could be debugged. 我太累了,对整个代码注释(这是非常糟糕的),所以我就写有问题的问题,以及如何平凡它可以进行调试。

First thing to do is to check if we get the number and return to main, hence: 首先要做的是检查我们是否获得数字并返回到main,因此:

int menu = read_input();
printf("got [%d]\n", menu);

Running this: 运行此:

[snip]
1
got [1]

So we indeed get to this point. 所以我们确实到了这一点。

As such now we check what is this compared to. 因此,现在我们检查一下这是什么。

int menu = read_input();
printf("got [%d] '1'=[%d]\n", menu, '1');

Let's run: 让我们运行:

1
got [1] '1'=[49]

So, menu stores an integer 1, while '1' is a character code for 1 in ascii, which, well, is not an integer 1. 因此, 菜单存储了一个整数1,而“ 1”是ascii中1的字符代码,而它并不是整数1。

In general I don't see what was the problem with narrowing it down. 总的来说,我认为缩小范围是什么问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM