Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无效的类型参数/不兼容的指针类型C_C_String_Pointers - Fatal编程技术网

无效的类型参数/不兼容的指针类型C

无效的类型参数/不兼容的指针类型C,c,string,pointers,C,String,Pointers,我知道以前有人问过这种形式的问题,但我很难找到一个适合我的情况 作为一个试图习惯C语言的人,我遇到了指针的问题,特别是字符串。我有一小部分错误不断地出现,我不能对我一直在做的错事耿耿于怀 我正在编写一个程序,它将读取username:password键/值,然后将它们与给定值进行比较。为此,我使用userpass结构: typedef struct { char user[BUF_MAX]; char pass[BUF_MAX]; } userpass; 以及以下代码: char *authT

我知道以前有人问过这种形式的问题,但我很难找到一个适合我的情况

作为一个试图习惯C语言的人,我遇到了指针的问题,特别是字符串。我有一小部分错误不断地出现,我不能对我一直在做的错事耿耿于怀

我正在编写一个程序,它将读取username:password键/值,然后将它们与给定值进行比较。为此,我使用userpass结构:

typedef struct {
char user[BUF_MAX];
char pass[BUF_MAX];
} userpass;
以及以下代码:

char *authThread(char *filename, char *request){

List_t logins;
char user[BUF_MAX];
char pass[BUF_MAX];
char *saveptr = NULL;
char *listptr = NULL;

char *username = strtok_r(request, ":", &saveptr);
char *password = strtok_r(NULL, ":", &saveptr);

char *failCode = malloc(sizeof (char)*BUF_MAX);
sprintf(failCode, "0:%s:0", username);

char *successCode = malloc(sizeof (char)*BUF_MAX);
sprintf(successCode, "1:%s:%s", username, ticketSecret);

if (List_init(&logins)){

  //Retrieve all the user:pass pairs from the auth file
  FILE *fp = fopen(filename, "r");
  while(fscanf(fp, "%s:%s", user, pass) != EOF){
    userpass new;
    //PROBLEM LINES BELOW+++++++++++++++++++++++++++++++++
    strcpy(new->user, user);
    strcpy(new->pass, pass);
    List_add_tail(&logins, &new);
  }//while
  fclose(fp);

  //See if the username/pass combination provided exists in the auth file
  for (;;){
    userpass *next = NULL;
    //PROBLEM LINE BELOW+++++++++++++++++++++++++++++++++
    List_next_node(&logins, &listptr, &next);
    if (next == NULL) break;

    //Match found, return required auth string
    if (strcmp(next->user, username) == 0 && strcmp(next->pass, password) == 0){
      return successCode;
    }//if
  }//for

  return failCode;

}//if
else{
  printf("Error creating auth list\n");
}//else

}//authThread
列表是一个链表实现。列表\下一个\节点函数的标题如下:

int List_next_node ( List_t *list, void **context, void **data );
我已经在上面的两行中标记了一个错误。当我试图编译时,我得到两个错误。在前两行,我得到:
的无效类型参数–->–

在第二行,我得到:
传递来自不兼容指针类型的–List\u next\u node–的参数2(3)

我可以看出这两个问题都是由变量类型不正确引起的,但我看不出这是怎么可能的。在第一种情况下,
new->user
应该是一个字符数组,就像
user
一样


在第二种情况下,List_next_节点接受三个参数;指向列表的指针、指向上下文指针的指针和指向数据指针的指针。据我所知,一切都是它应该是的类型。我只能想象在C语言中字符串(即字符数组)的工作方式会出现一些问题。

新的
是在堆栈上本地声明的。它不是指针,因此需要更改

userpass new;
strcpy(new->user, user);
strcpy(new->pass, pass);

根据
List\u add\u tail
的实现情况(我在您的问题中看不到),这可能不是唯一的问题
new
List\u add\u tail
返回后超出范围,除非将项目添加到列表中获取副本,否则列表将保留指向易于重用的内存的指针

如果
List\u add\u tail
在其第二个参数中没有创建
userpass*
的副本,您应该将代码更改为

userpass* new = malloc(sizeof(*new));
strcpy(new->user, user);
strcpy(new->pass, pass);
List_add_tail(&logins, &new);

(请注意,在最后一个示例中,
new
是一个指针,因此我们必须使用取消引用操作符
->
再次访问其成员。)

错误1

您已经将变量
new
定义为userpass结构,但是您可以像指针一样访问其内部属性

userpass new;
...
strcpy(new->user, user); // new->user is equivalent to (*new).user
strcpy(new->pass, pass);
相反,请使用
运算符:

strcpy(new.user, user);
strcpy(new.pass, pass);
您应该动态地分配userpass结构,以便它们不会超出范围

错误2(这是一个警告)

您的参数
&listptr
属于
char**
类型,但函数应为
void**
。您可以强制转换参数以删除警告:

 List_next_node(&logins, (void **) &listptr, (void **) &next);

类似地,
&next
userpass**
,它期望
void**

它看起来像
userpass
是一个数据type@TaylorFlores是的,它是一个结构的typedef,显示在问题代码的正上方。我以前从未见过这样使用数据类型,它看起来很奇怪。这不是
c++
?编辑:没关系,语法高亮让我困惑。Taylor Flores:这是C,不是C++。否则,“new”将是一个不能声明为变量的关键字。一般来说,您应该通读C以完全理解,但简而言之,声明为
struct foo{…}的类型必须用作
struct foo bar
以创建该类型的变量。如果您使用这样的typedef,您可以像使用正则变量一样使用typedef。这主要是一种风格选择,因为它基本上编译成相同的代码。@Taywee,我编辑了我的评论。语法突出显示让我困惑,仅此而已。我不需要阅读
C
谢谢你的回答!这涵盖了simonc没有的东西——对void**的强制转换——但不幸的是,我只能接受一个响应,也许它们应该一起编辑。
 List_next_node(&logins, (void **) &listptr, (void **) &next);