在指向结构的指针数组中填充字符串

时间:2022-07-31 21:16:17

I'm reviewing pointers in C and am creating some practice exercises for myself. I thought it would be good to read in some structs via an array of struct pointers, then display and sort the array. The problem I'm having is, I feel, rather basic. The below code reads in the first entry, however the firstName string is always null. After printing the first struct and continuing the second it goes 'boom' at the time to read into the firstName string. I thought I initialized the char strings correctly in initParty(), so I'm not sure what the problem is here. Any ideas?

我在回顾C中的指针,并为自己创建了一些练习练习。我认为通过一组struct指针读取一些结构,然后显示和排序数组会很好。我觉得我遇到的问题是相当基本的问题。下面的代码读入第一个条目,但firstName字符串始终为null。打印完第一个结构并继续第二个结构后,它会在当时读取firstName字符串。我以为我在initParty()中正确初始化了char字符串,所以我不确定这里的问题是什么。有任何想法吗?

Sample run:

*(gdb) run Starting program: /home/remnux/C/struct Enter the firstname: john Enter the lastname: smith Enter the ssn: 1234 (null) smith, 1234

*(gdb)运行启动程序:/ home / remnux / C / struct输入名字:john输入姓氏:smith输入ssn:1234(null)smith,1234

Program received signal SIGSEGV, Segmentation fault. 0x00000000004009a4 in getParty (p=0x0) at struct.c:51 51 scanf("%s", p->firstName); (gdb)*

程序接收信号SIGSEGV,分段故障。在struct.c的getParty(p = 0x0)中的0x00000000004009a4:51 51 scanf(“%s”,p-> firstName); (GDB)*

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

struct person{
    char *firstName;
    char *lastName;
    int ssn;
  };  

void print(struct person* p){ 
  printf("\n%s ", p->firstName);
  printf("%s, ", p->lastName);
  printf("%d\n ", p->ssn);
}

bool isGreaterThan(struct person *p1, struct person *p2){
  return (strcmp(p1->firstName > p2->firstName) > 0)
    || ((strcmp(p1->firstName > p2->firstName) ==  0) && (strcmp(p1->lastName > p2->lastName) > 0)) 
    || ((strcmp(p1->firstName > p2->firstName) ==  0) && (strcmp(p1->lastName > p2->lastName) == 0)) && (p1->ssn - p2->ssn > 0); 
}

void printArray(struct person** parray, int size){
  int i;
  for(i = 0; i < size; i++)
    printf("%s %s, %d", parray[i]->firstName, parray[i]->lastName, parray[i]->ssn);
}

void sort(struct person** parray, int size){
  int i, j;
  for(i = 0; i < size; i++)
    for(j = 0; j < size-1; j++){
      if(isGreaterThan(parray[j], parray[j+1])){
        struct person *temp = parray[j];
        parray[j] = parray[j+1];
        parray[j+1] = temp;
      }   
    }    
return;
}

void initParty(struct person *p){
    p = (struct person*)malloc(sizeof(struct person));
    p->firstName = (char*)malloc(100 * sizeof(char));
    p->lastName = (char*)malloc(100 * sizeof(char));
}

void getParty(struct person *p){
  int ch;
  printf("\nEnter the firstname: ");
  scanf("%s", p->firstName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the lastname: ");
  scanf("%s", p->lastName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the ssn: ");
  scanf("%d", &(p->ssn));
  while((ch = getchar()) != '\n' && ch != EOF);
}

int main(){
  int i, ch, size = 2;
//  printf("Input the number of people you wish to enter: ");
//  scanf("%d", &size);
//  while((ch = getchar()) != '\n' && ch != EOF);
  struct person *parray[size];
  for(i = 0; i < size; i++){
    initParty(parray[i]);
    getParty(parray[i]);
    print(parray[i]);
  }
  sort(parray, size);
  printArray(parray, size);
}

Edit, after eliminating the warnings when compiling with -Wall:

在使用-Wall编译时消除警告后编辑:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

struct person{
    char *firstName;
    char *lastName;
    int ssn;
  };  

void print(struct person* p){ 
  printf("\n%s ", p->firstName);
  printf("%s, ", p->lastName);
  printf("%d\n ", p->ssn);
}

/*bool isGreaterThan(struct person *p1, struct person *p2){
  return ((strcmp(p1->firstName > p2->firstName) > 0)
    || ((strcmp(p1->firstName > p2->firstName) ==  0) && (strcmp(p1->lastName > p2->lastName) > 0))
    || ((strcmp(p1->firstName > p2->firstName) ==  0) && (strcmp(p1->lastName > p2->lastName) == 0) && (p1->ssn - p2->ssn > 0))); 
}*/

void printArray(struct person** parray, int size){
  int i;
  for(i = 0; i < size; i++)
    printf("%s %s, %d", parray[i]->firstName, parray[i]->lastName, parray[i]->ssn);
}

/*void sort(struct person** parray, int size){
  int i, j;
  for(i = 0; i < size; i++)
    for(j = 0; j < size-1; j++){
      if(isGreaterThan(parray[j], parray[j+1])){
        struct person *temp = parray[j];
        parray[j] = parray[j+1];
        parray[j+1] = temp;
      }
 }    
  return;
} */

void initParty(struct person *p){
    p = (struct person*)malloc(sizeof(struct person));
    p->firstName = (char*)malloc(100 * sizeof(char));
    p->lastName = (char*)malloc(100 * sizeof(char));
}

void getParty(struct person *p){
  int ch;
  printf("\nEnter the firstname: ");
  scanf("%s", p->firstName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the lastname: ");
  scanf("%s", p->lastName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the ssn: ");
  scanf("%d", &(p->ssn));
  while((ch = getchar()) != '\n' && ch != EOF);
}

int main(){
  int i, size = 2;
//  printf("Input the number of people you wish to enter: ");
//  scanf("%d", &size);
//  while((ch = getchar()) != '\n' && ch != EOF);
  struct person *parray[size];
  for(i = 0; i < size; i++){
    initParty(parray[i]);
    getParty(parray[i]);
    print(parray[i]);
  }
  //sort(parray, size);
  printArray(parray, size);
  return 0;
 }    
  return;
} */

void initParty(struct person *p){
    p = (struct person*)malloc(sizeof(struct person));
    p->firstName = (char*)malloc(100 * sizeof(char));
    p->lastName = (char*)malloc(100 * sizeof(char));
}

void getParty(struct person *p){
  int ch;
  printf("\nEnter the firstname: ");
  scanf("%s", p->firstName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the lastname: ");
  scanf("%s", p->lastName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the ssn: ");
  scanf("%d", &(p->ssn));
  while((ch = getchar()) != '\n' && ch != EOF);
}

int main(){
  int i, size = 2;
//  printf("Input the number of people you wish to enter: ");
//  scanf("%d", &size);
//  while((ch = getchar()) != '\n' && ch != EOF);
  struct person *parray[size];
  for(i = 0; i < size; i++){
    initParty(parray[i]);
    getParty(parray[i]);
    print(parray[i]);
  }
  //sort(parray, size);
  printArray(parray, size);
  return 0;
 }    
  return;
} */

void initParty(struct person *p){
    p = (struct person*)malloc(sizeof(struct person));
    p->firstName = (char*)malloc(100 * sizeof(char));
    p->lastName = (char*)malloc(100 * sizeof(char));
}

void getParty(struct person *p){
  int ch;
  printf("\nEnter the firstname: ");
  scanf("%s", p->firstName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the lastname: ");
  scanf("%s", p->lastName);
  while((ch = getchar()) != '\n' && ch != EOF);
  printf("\nEnter the ssn: ");
  scanf("%d", &(p->ssn));
  while((ch = getchar()) != '\n' && ch != EOF);
}

int main(){
  int i, size = 2;
//  printf("Input the number of people you wish to enter: ");
//  scanf("%d", &size);
//  while((ch = getchar()) != '\n' && ch != EOF);
  struct person *parray[size];
  for(i = 0; i < size; i++){
    initParty(parray[i]);
    getParty(parray[i]);
    print(parray[i]);
  }
  //sort(parray, size);
  printArray(parray, size);
  return 0;
}

1 个解决方案

#1


0  

Since the contributions have all been comments and not answers I suppose I'll answer this myself. The problem is that I was passing the pointer to the struct to the function, and hence the structure was modifying the local pointer copy since C is pass-by-value. If one wishes to modify the object pointed to then the pointer must be referenced, so that the main object can be modified when deferenced inside the function. The following changes did the trick:

由于贡献都是评论而不是答案,我想我会自己回答这个问题。问题是我将指向结构的指针传递给函数,因此结构正在修改本地指针副本,因为C是按值传递的。如果希望修改指向的对象,则必须引用指针,以便在函数内部引用时可以修改主对象。以下更改可以解决问题:

void initParty(struct person **p){
    *p = (struct person*)malloc(sizeof(struct person));
    (*p)->firstName = (char*)malloc(100 * sizeof(char));
    (*p)->lastName = (char*)malloc(100 * sizeof(char));
}

And the call:

电话:

  initParty(&(parray[i]));

#1


0  

Since the contributions have all been comments and not answers I suppose I'll answer this myself. The problem is that I was passing the pointer to the struct to the function, and hence the structure was modifying the local pointer copy since C is pass-by-value. If one wishes to modify the object pointed to then the pointer must be referenced, so that the main object can be modified when deferenced inside the function. The following changes did the trick:

由于贡献都是评论而不是答案,我想我会自己回答这个问题。问题是我将指向结构的指针传递给函数,因此结构正在修改本地指针副本,因为C是按值传递的。如果希望修改指向的对象,则必须引用指针,以便在函数内部引用时可以修改主对象。以下更改可以解决问题:

void initParty(struct person **p){
    *p = (struct person*)malloc(sizeof(struct person));
    (*p)->firstName = (char*)malloc(100 * sizeof(char));
    (*p)->lastName = (char*)malloc(100 * sizeof(char));
}

And the call:

电话:

  initParty(&(parray[i]));