【问题标题】:My pid identifier not expected我的 pid 标识符不是预期的
【发布时间】:2018-05-13 06:55:36
【问题描述】:

所以在学校我得到了这个练习,我需要编写一个程序来计算一个数字是否是质数。这个程序应该使用父子进程,并且应该使用strtoul将argv转换为unsigned long。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>

void checkprime(unsigned long num);

int main(int argc, char *argv, char *env)
{       
strtoul(argv, NULL, 0);

pid_t pid = fork(); 

if(pid == 0)
{
    unsigned long number;

    printf("\nGive number to check: \n");
    scanf("%lu",&number);

    checkprime(number);
}
else if(pid < 0)
{
    perror("Fork Failed!");
}
else
{
    int status = -1, result;
    waitpid(pid, &status, 0);
    result = WEXITSTATUS(status);

    if(result == 1)
    {       
        printf("this is a prime number\n");
    }
    else if(status < 0)
    {
        perror("Something Failed");
    }
    else
    { 
        printf("this is not a prime number\n");
    }
}
return 0;
}

void checkprime(unsigned long num)
{
int i;
for(i = 2; i < num; i++)
{
    if(num % i == 0)
    {
        exit(0);
    }
}
exit(1);
}

所以当我尝试编译它时,它会说:第 13 行:不需要标识符。错误代码 1。

第 13 行的代码是:pid_t pid = fork();

现在我的问题是:为什么会出现这个错误?

已修复,感谢大家的帮助。我很感激。

【问题讨论】:

  • pid_t = pid = fork(); 的目的是什么?这根本不是有效的 C 语法。
  • 更糟糕的是,您修复了您在此处显示的代码中的错误!您应该始终复制粘贴代码,这样就不会引入其他错误,或者像在这种情况下修复错误。现在这个问题是没有价值的,因为没有问题。
  • 对不起,我的意思是:pid_t pid = fork();
  • 查看man7.org/linux/man-pages/man3/strtol.3.html 并将您的调用移至局部变量声明下方的strtol(...)
  • 另外,这也应该教你复制粘贴错误。完整、完整、未经修改的文本。

标签: c compilation fork pid


【解决方案1】:

您可以通过将i &lt; num 更改为i &lt; num/2 来使用更短的主查找器循环。

这是main() 参数的标准之一:

(int argc, char **argv)

打开 gcc 标志:-Wall 以查看代码中的所有警告。

正如@cleblanc 在其中一个答案中所说,将strtoul() 的返回值存储到变量long int val = strtoul(argv[1], NULL, 0);

我们从命令行参数传递数字进行检查, argv[1] 指的是我们用

运行程序时的数字

./素数 15

代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

void checkprime(unsigned long num);

int main(int argc, char **argv)
{ 

    long int val = strtoul(argv[1], NULL, 0);

    pid_t pid = fork(); 

    if(pid == 0){   
        checkprime(val);
    }
    else if(pid < 0){
        perror("Fork Failed!");
    }
    else{
        int status = -1, result;
        waitpid(pid, &status, 0);
        result = WEXITSTATUS(status);
        if(result == 1){       
            printf("Prime\n");
        }
        else if(status < 0){
            perror("Something Failed");
        }
        else{ 
            printf("Not prime\n");
        }
    }
    return 0;
}

void checkprime(unsigned long num)
{
    int i;
    for(i = 2; i < num/2; i++){
        if(num % i == 0){
            exit(0);
        }
    }
    exit(1);
}

编译,运行

gcc -Wall prime.c -o prime

./prime 15

【讨论】:

  • 仅代码(或主要代码)问题是题外话。恕我直言,只有代码的答案是不受欢迎的。加几句解释(英文)
【解决方案2】:

一些旧版本的编译器接受C89(不是C99C11)作为默认的C 方言。您至少需要 C99(因为您在声明之后有声明)。

如果您在某些旧 Linux 发行版上使用某些旧版本的 GCC,请尝试编译 with gcc -std=gnu99 -Wall -Wextra -g 其中 -std=gnu99 设置 C 方言(您也可以使用 -std=c99 或更好),-Wall -Wextra要求警告,-g 需要调试信息(在DWARF 中,用于gdb debugger)。更好的是,将您的 GCC 升级到最新版本(如 2017 年 11 月的 GCC 7),其默认为 C11 和 GNU extensions

或者放上声明

pid_t pid= 0;

(我更喜欢在C中系统地初始化变量)

语句之前

 strtoul(argv, NULL, 0); //useless call, you need to store the result
 pid= fork(); 

【讨论】:

  • 次要评论:一般来说,我建议使用 -std=gnu99 而不是 -std=c99 来获得 C99 功能,除非您特别想避免 GNU 扩展。直到 GCC 4.x,C 编译的默认值是-std=gnu90。从 GCC 5.x 开始,默认值为 -std=gnu11(跳过 gnu99 并直接使用带有 GNU 扩展的 C 2011 标准)。
【解决方案3】:

编译器告诉您它不希望在该行遇到标识符pid_t,因为前一行不是标识符。您需要在作用域的顶部声明变量,并在其下方放置其他代码。你可以这样做

int main(int argc, char *argv, char *env)
{       
    long int val=strtoul(argv, NULL, 0);
    pid_t pid = fork(); 
    ...

int main(int argc, char *argv, char *env)
{       
    pid_t pid = fork(); 
    strtoul(argv, NULL, 0);
    ...

但是您缺少从 strtol 返回的值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    相关资源
    最近更新 更多