C 通过双指针函数变量从结构数组访问数据

C 通过双指针函数变量从结构数组访问数据,c,C,我正在做一个函数,它是一个更大程序的一部分。我的C指针技能有些生疏,所以我需要一些帮助 我不断地遇到分段错误,我觉得我的问题有一个非常简单的解决方案,任何解释都会有帮助 本质上,我有一个空的结构数组,需要作为双指针传递给函数。该函数将打开并读取一个文件,该文件保存在结构数组中 我需要将其作为双指针传递 这就是我到目前为止所做的: struct node{ int first_value; int second_value; }; unsigned char readFuncti

我正在做一个函数,它是一个更大程序的一部分。我的C指针技能有些生疏,所以我需要一些帮助

我不断地遇到分段错误,我觉得我的问题有一个非常简单的解决方案,任何解释都会有帮助

本质上,我有一个空的结构数组,需要作为双指针传递给函数。该函数将打开并读取一个文件,该文件保存在结构数组中

我需要将其作为双指针传递

这就是我到目前为止所做的:

struct node{
    int first_value;
    int second_value;
};

unsigned char readFunction(char *fileName, int *limit, struct node **arrayToFill){ //Many more variables passed, but I removed it for the sake of simplicity
    FILE *input;
    input = fopen(fileName, "r");
    if (input == NULL) {
        printf("error: could not read the input file!\n");
    }
    int i=0;
    int temp1, temp2;
    for(i=0; i<(*limit); i++){
        fscanf(input, "(%d, %d)", &temp1, &temp2);
        (*(arrayToFill+i))->first_value = temp1;
        (*(arrayToFill+i))->second_value= temp2;
    }
    //More code
    return 0; //Actually returns another array but that's irrelevant.
} 

int main(){
    //NOTE: I just created these variables for the sake of showing it on StackOverflow, I still get a Segmentation Fault error when I run the program.
    char name[9] = {'t', 'e', 's', 't', '.', 't','x','t', '\0'};
    struct node arrayToPass[10];
    struct node *pointer = &arrayToPass;
    struct node **data = &pointer;
    unsigned char returnedVal;
    int limit = 10;

    returnedVal = readFunction(&name, &limit, data);

    return 0;
}
struct节点{
int第一值;
int第二值;
};
unsigned char readFunction(char*fileName,int*limit,struct node**arrayToFill){//传递了更多变量,但为了简单起见,我删除了它
文件*输入;
输入=fopen(文件名,“r”);
如果(输入==NULL){
printf(“错误:无法读取输入文件!\n”);
}
int i=0;
int temp1,temp2;
对于(i=0;i初始值=temp1;
(*(arrayToFill+i))->second_值=temp2;
}
//更多代码
return 0;//实际返回另一个数组,但这与此无关。
} 
int main(){
//注意:我创建这些变量是为了在StackOverflow上显示它,但在运行程序时仍然会出现分段错误。
字符名[9]={t','e','s','t','t','x','t','0'};
结构节点arrayToPass[10];
结构节点*指针=&arrayToPass;
结构节点**数据=&指针;
未签名字符返回值;
整数极限=10;
returnedVal=readFunction(&name,&limit,data);
返回0;
}

提前谢谢!

我相信您可能需要以下内容

#include <stdio.h>

struct node{
    int first_value;
    int second_value;
};

unsigned char readFunction(char *fileName, int limit, struct node *arrayToFill){ //Many more variables passed, but I removed it for the sake of simplicity
    FILE *input;
    input = fopen(fileName, "r");
    if (input == NULL) {
        printf("error: could not read the input file!\n");
    }
    int i=0;
    int temp1, temp2;
    for(i=0; i<limit; i++){
        fscanf(input, "(%d, %d)", &temp1, &temp2);
        arrayToFill[i].first_value = temp1;
        arrayToFill[i].second_value = temp2;
    }
    //More code
    return 0; //Actually returns another array but that's irrelevant.
} 

int main(){
    //NOTE: I just created these variables for the sake of showing it on StackOverflow, I still get a Segmentation Fault error when I run the program.
    char name[9] = "test.txt";
    struct node arrayToPass[10];
    unsigned char returnedVal;
    int limit = 10;

    returnedVal = readFunction(name, limit, arrayToPass);

    return 0;
}
#包括
结构节点{
int第一值;
int第二值;
};
unsigned char readFunction(char*fileName,int limit,struct node*arrayToFill){//传递了更多变量,但为了简单起见,我删除了它
文件*输入;
输入=fopen(文件名,“r”);
如果(输入==NULL){
printf(“错误:无法读取输入文件!\n”);
}
int i=0;
int temp1,temp2;

对于(i=0;i您有几个问题。第一个问题是您错误地使用了
arrayToPass[10]
指针,您只需要:

int main (void) {

    struct node arrayToPass[10];
    int limit = 10;

    printf ("return: %hhu\ncontent:\n", readFunction(NULL, &limit, &arrayToPass));
    for (int i = 0; i < limit; i++)
        printf ("%5d   %5d\n", 
                arrayToPass[i].first_value, arrayToPass[i].second_value);

}
注意:使用三元运算符,允许将
NULL
作为
fileName
传递,以便从
stdin
读取,这只是为了我的方便)

另请注意:由于您在
main()中声明了
struct node arrayToPass[10];
具有自动存储持续时间)
,您不需要传递指针的地址,只要在函数中地址可以更改时传递指针的地址——例如,如果您在指针上调用
realloc
,则只需传递指针的地址。其他答案将指向该点。)

需要传递
struct node**
struct node(*)[10]
或简单地传递
struct node*
之间的区别归结为如何为原始集合分配内存。如果您已经这样做,请在
main()中声明
struct node arrayToPass[10];
通过自动存储持续时间,数组的存储是固定的。在访问时,数组将转换为指针(
struct node*
),您只需将数组本身作为参数传递即可。(但限制为不超过最初声明的元素数)

但是,如果在
main
中为
arrayToPass
分配了存储类型(例如
struct node*arrayToPass=malloc(10*sizeof*arrayToPass);
,那么如果需要更改存储量,例如
readFunction()中分配的内存块可以容纳的
stuct node
,则必须传递指针的地址,因此如果发生了重新分配,并且内存块的起始地址发生了更改,则会在调用者中看到该更改(
main()
此处)。在这种情况下,当传递
struct node*
的地址时,您的类型将变为
struct node**
。(因为您采用的是指针地址而不是数组地址)

由于无法重新分配arrayToPass,并且在将其传递到
readFunction()
之前存储是固定的,因此不需要传递地址,您可以消除一级指针间接寻址,只需将数组作为type
struct node*
传递。这将函数中的访问简化为
arrayToFill[i].first_value=temp1;
[…]
充当指针的解引用,就像
->
一样

您还可能希望将返回类型从
unsigned char
更改为
size\u t
,并返回结构中填充的元素数(有意义的返回)——或者您可以像我一样更新
limit
指针——这是您的选择

完整的例子是:

#include <stdio.h>

struct node {
    int first_value;
    int second_value;
};

unsigned char readFunction (char *fileName, int *limit, struct node (*arrayToFill)[10])
{ //Many more variables passed, but I removed it for the sake of simplicity
    FILE *input;
    input = fileName ? fopen (fileName, "r") : stdin;
    if (input == NULL) {
        printf("error: could not read the input file!\n");
    }
    int i=0;
    int temp1, temp2;
    while (i < *limit && fscanf(input, " (%d, %d)", &temp1, &temp2) == 2) {
        (*arrayToFill)[i].first_value = temp1;
        (*arrayToFill)[i].second_value = temp2;
        i++;
    }
    *limit = i;

    return 0; //Actually returns another array but that's irrelevant.
} 

int main (void) {

    struct node arrayToPass[10];
    int limit = 10;

    printf ("return: %hhu\ncontent:\n", readFunction(NULL, &limit, &arrayToPass));
    for (int i = 0; i < limit; i++)
        printf ("%5d   %5d\n", 
                arrayToPass[i].first_value, arrayToPass[i].second_value);

}
请注意
fscanf
格式字符串中的更改,包括在左括号
'(
使用
'\n'
(以及任何前导空格)之前的额外
'
(空格)。除非检查返回值(例如
fscanf(input)(%d,%d)),否则无法正确使用任何输入函数,&temp1,&temp2)==2

示例使用/输出

$ ./bin/ptrtoarraystruct < dat/2x8rand.txt
return: 0
content:
17987    1576
12911    4488
30688    5875
25617   16643
 8999   26249
29270   31857
 8954    2094
21390   27676
$。/bin/ptrtoarraystruct

仔细检查一下,如果您还有其他问题,请告诉我。

好吧,
指针
不是
struct node**arrayToFill
类型,而是
struct node*arrayToFill
类型。请启用编译器警告并听取它们。注意
[-Wincompatible pointer types]
警告:哦,我的天
$ cat dat/2x8rand.txt
(17987, 1576)
(12911, 4488)
(30688, 5875)
(25617, 16643)
(8999, 26249)
(29270, 31857)
(8954, 2094)
(21390, 27676)
$ ./bin/ptrtoarraystruct < dat/2x8rand.txt
return: 0
content:
17987    1576
12911    4488
30688    5875
25617   16643
 8999   26249
29270   31857
 8954    2094
21390   27676