首页 > 解决方案 > 错误:'->' 的类型参数无效(有 'Queue {aka struct Queue}

问题描述

我正在尝试使用这种格式的实例|指令读取文件......就像这样 1 01 01 12 12 33,其中第一个数字是实例,之后是指令的数字。每行都有自己的 id。所以在那个例子中,如果是第一行,id 是 1,下一行是 2,依此类推。

我想要做的是按我拥有的 PCB 结构这样的结构对信息进行分组。每行都有一个 id 和一个队列,我在其中存储指令部分的每个编号。

我有一个结构,里面有一些变量和一个队列。问题是队列不起作用。

typedef struct Queue
{
  int sizeQueue;
  int limit;
  Node *head;


}Queue;

typedef struct PCB
{
 int id;
 int program_counter;
 int size;
 Queue pointer_instrucoes;
 int instante;

}PCB;

typedef struct Node
{
 PCB *element;
 Node *next;

}Node;

主要是我用队列调用结构来存储一些值。

PCB *p=new_pcb(contador);
....
p->pointer_instrucoes->head=atoi(s2); //s2 is the some number of the //instruction

但我收到了这个错误:'->'的无效类型参数(有'Queue {aka struct Queue}

MVCE:

主文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //para o output
#include "queue2.h"

int le_ficheiro(char* filename) {
FILE *ficheiro=fopen(filename,"r");
size_t len=0;
char *line=NULL;
ssize_t read;
char *s1;//string antes do primeiro espaço
char *s2;//string depois do primeiro espaço
char *sp; //linha toda
if(ficheiro==NULL) {
    exit(EXIT_FAILURE);
}
int contador=1; //onde comeca o id

while((read = getline (&line, &len,ficheiro))!=-1)   //le de linha a linha
{
    PCB *p=new_pcb(contador);
    sp=strchr(line,' ');
    if(!sp)
    {
        exit(EXIT_FAILURE);
    }
    s1=strndup(line,sp-line);
    s2=sp+1;
    p->instante=atoi(s1); //converte char to int

    printf("Instante: %d\n",p->instante);
    printf("Id: %d\n",p->id);

    p.pointer_instrucoes.head=atoi(s2);

    printf("%d\n",p->pointer_instrucoes->head);



    printf("Retrieved line of length %zu:\n",read);
    printf("%s\n",s2);
    printf("Aqui : %c\n",line[0]);
    contador++;
}
 fclose(ficheiro);
 if(line)
    free(line);
    free(s1);
 exit(EXIT_SUCCESS);

 }


int main()
{
  char name[50];
  printf("Name of the file: ");
  scanf("%s",name);
  le_ficheiro(name);
  return 0;

}

queue2.h 文件

#include <stdbool.h>

typedef struct PCB PCB;
typedef struct Node Node;
typedef struct Queue Queue;
typedef struct Queue
{
  int sizeQueue;
  int limit;
  Node *head;


 }Queue;
typedef struct PCB
{
  int id;
  int program_counter;
  int size;
  Queue pointer_instrucoes;
  int instante;

 }PCB;

 typedef struct Node
 {
  PCB *element;
  Node *next;

  }Node;

 PCB * new_pcb(int id); 
 Node * new_node(PCB * e);
 Queue * new_queue(int limit);

队列2.c

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


Node * new_node(PCB * e)
 {
  Node *n=malloc(sizeof(Node));
  n->element=e;
  n->next=NULL;
  return n;
  }




Queue * new_queue(int limit)
{
   Queue *q=malloc(sizeof(Queue));
   q->limit=limit;
   q->head=NULL;
   q->sizeQueue=0;

   return q;

     }

   PCB * new_pcb(int id)
{
   PCB *p = malloc(sizeof(PCB));
   p->id=id;
   p->pointer_instrucoes=0;
   p->program_counter=0;
   p->size=0;
   return p;
   }

输入示例:1 01 02 03 04 05

2 01 02 03 02 11

标签: c

解决方案


你的问题是初级的,你需要花时间去竞争le_ficheiro。对于初学者,您不能将结果分配给atoi(s2)to p.pointer_instrucoes.headhead不是一个int,它是一个指向的指针 Node*。您违反了严格别名规则 C11 标准 - §6.5 表达式 (p6,7)并且可能还有十几个其他人试图Node*通过分配 anint作为其值来访问和修改。

当不确定(未初始化)时,您调用未定义行为尝试访问。p->id

通过尝试手动将值与lineusing分开,您使生活变得比实际需要的要困难得多strchr(line, ' ')。您已经拥有包含在中的所有值line,您可以使用在一次调用sscanf中解析所有六个值并验证该行,例如int

    while ((read = getline (&line, &len,ficheiro)) != -1) //le de linha a linha
    {
        int a, b, c, d, e, f;
        if (sscanf (line, "%d %d %d %d %d %d", 
                    &a, &b, &c, &d, &e, &f) != 6) {
            fprintf (stderr, "error: failed to parse line '%d'.\n",
                    contador);
            continue;
        }
        PCB *p = new_pcb (contador);
        if (!p)  /* Validate EVERY Allocation */
            exit (EXIT_FAILURE);

但是,在您可以验证每个分配并避免潜在地调用Undefined Behavior之前,您必须从 提供有意义的返回值new_node, new_queue & new_pcb,以指示成功/失败,例如

Node *new_node (PCB *e)
{
    Node *n = malloc (sizeof *n);
    if (!n) {   /* Validate EVERY Allocation */
        perror ("malloc-new_node");
        return NULL;  /* return NULL on failure */
    }
    n->element = e;
    n->next = NULL;

    return n;
}

Queue *new_queue (int limit)
{
    Queue *q = malloc (sizeof *q);   /* typo in declaration */
    if (!q) {
        perror ("malloc-new_queue");
        return NULL;
    }
    q->limit = limit;
    q->head = NULL;
    q->sizeQueue = 0;

    return q;
}

PCB *new_pcb (int id)
{
    PCB *p = malloc (sizeof *p);
    if (!p) {
        perror ("malloc-new_pcb");
        return NULL;
    }
    p->id = id;
    p->pointer_instrucoes = 0;
    p->program_counter = 0;
    p->size = 0;

    return p;
}

很明显,你已经完成了一部分,le_ficheiro然后就放弃了。它还远未完成,您的代码中甚至仅使用了每行输入中的一个数据值(其余的您尝试打印为文本只是为了查看您的s2指针指向的位置 - 但没有进一步或有意义地使用这些值)

您甚至不需要调用new_node来创建一个Node*可以想象分配给p.pointer_instrucoes.head. 一步一步来。您需要在new_node某处调用,le_ficheiro以便您有一个可以分配给的指针p.pointer_instrucoes.head。它没有任何魔力,但是在尝试使用它们之前,您必须有条不紊地确保每个值和每个结构的每个成员都已创建并使用值正确初始化。

基本上你有一个le_ficheiro需要继续完成的外壳,从一个更好的起始位置开始工作:

int le_ficheiro (char* filename) 
{
    FILE *ficheiro = fopen (filename,"r");
    size_t len = 0;
    ssize_t read = 0;
    int contador = 1;   //onde comeca o id

    if (ficheiro == NULL) {
        perror ("fopen-filename");
        exit (EXIT_FAILURE);
    }

    while ((read = getline (&line, &len,ficheiro)) != -1) //le de linha a linha
    {
        int a, b, c, d, e, f;
        if (sscanf (line, "%d %d %d %d %d %d", 
                    &a, &b, &c, &d, &e, &f) != 6) {
            fprintf (stderr, "error: failed to parse line '%d'.\n",
                    contador);
            continue;
        }
        PCB *p = new_pcb (contador);
        if (!p)
            exit (EXIT_FAILURE);

        p->instante = a;
        printf ("Instante: %d\n", p->instante);

        /* you must assign and allocate as necessary to use remaining
         * values read from file HERE. Nowhere do you assign p->id
         * before attempting to print, etc...
         */
        printf ("Id: %d\n", p->id);

        /* you cannot assign atoi(s2) to p.pointer_instrucoes.head.
         * it expects type 'Node *', not int.
         */
        // p.pointer_instrucoes.head = FIXME;
        // printf ("%d\n", p->pointer_instrucoes->head);
        contador++;
    }
    fclose(ficheiro);

    free (line);
    free(s1);

    exit(EXIT_SUCCESS);
}

当你陷入编写函数的困境时,不要放弃。相反,请参阅如何调试小程序并与鸭子交谈......真的,它有帮助:)


推荐阅读