当函数打印指针数组的内容时,c程序崩溃

当函数打印指针数组的内容时,c程序崩溃,c,function,crash,C,Function,Crash,我正在学习C语言。我编写了一个程序,从文本文件中读取数据并打印出来。在构建过程中,编译器没有给出错误。然而,当我试图运行它时,程序崩溃了。我检查了当printTable函数被删除时,程序运行并在main()中打印循环中的内容。我还试图删除变量“total”,但程序仍然崩溃。有什么问题 #include<stdio.h> #include<stdlib.h> typedef struct{ char *country; int females; int males; }p

我正在学习C语言。我编写了一个程序,从文本文件中读取数据并打印出来。在构建过程中,编译器没有给出错误。然而,当我试图运行它时,程序崩溃了。我检查了当
printTable
函数被删除时,程序运行并在
main()
中打印循环中的内容。我还试图删除变量“
total
”,但程序仍然崩溃。有什么问题

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

typedef struct{
char *country;
int females;
int males;
}person_count;

void printTable(person_count *data[]){
    printf("Country  Females  Males  Total\n");
    int i;
    int total[158];
    for(i=0;i<158;i++){

        total[i]=data[i]->females+data[i]->males;

        printf("%15s  %7i  %7i  %8i\n",data[i]->country,data[i]->females,data[i]->males,total[i]);
    }
}


int main(){
    person_count *data[158];

    FILE *eduData=fopen("SecondaryEd2005.txt","r");
    if(eduData==NULL){
        printf("File not found.");
        exit(1);
    }
    printf("File opened successfully.\n");

    int k;
    for(k=0;k<158;k++){
        data[k]=malloc(sizeof(person_count));
        char place[20];
        fscanf(eduData,"%s %i %i\n",place,&data[k]->females,&data[k]->males);
        data[k]->country=place;
        printf("%s %i %i\n",data[k]->country,data[k]->females,data[k]->males);
    }

    printTable(data);

    fclose(eduData);

    return 0;
}
#包括
#包括
类型定义结构{
char*国家;
智力女性;
智力男性;
}人数;;
作废打印表(人数*数据[]){
printf(“国家/地区女性/男性总数”);
int i;
整数总计[158];
对于(i=0;ifemales+数据[i]>雄性;
printf(“%15s%7i%7i%8i\n”,数据[i]>国家,数据[i]>女性,数据[i]>男性,总数[i]);
}
}
int main(){
人数*数据[158];
文件*eduData=fopen(“SecondaryEd2005.txt”,“r”);
if(eduData==NULL){
printf(“未找到文件”);
出口(1);
}
printf(“文件已成功打开。\n”);
int k;
对于(k=0;kfemales,&data[k]->雄性);
数据[k]->国家=地点;
printf(“%s%i%i\n”,数据[k]->国家,数据[k]->女性,数据[k]->男性);
}
打印表(数据);
fclose(教育数据);
返回0;
}
txt文件内容示例:

比利时391138423401 伯利兹1559115786 贝宁154266 281183 百慕大24942262
不丹19870 22274

您应该更改您的人员计数结构:

typedef struct{
    char country[20];
    int females;
    int males;
}person_count;
data[k]->country=place;
应替换为
memcpy(data[k]->country,place,20*sizeof(char));

WhozCraig在他的评论中给了你答案。你的代码复制了一个指针,这个指针在下一次循环迭代中丢失了


请注意,只有当您的国家/地区少于19个字符时,此代码才有效。您也可以使用char*指针,但在这种情况下,您必须分配内存并在使用后释放内存。

我为您修复了程序。最重要的是将country设置为一个固定长度的字符数组,而不是指针。此外,还需要设置s请释放分配给程序的所有内存,否则会产生内存泄漏

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

typedef struct{
  char country[20]; //fixed to reflect country field better
  int females;
  int males;
}person_count;

void printTable(person_count *data[],int items){
  items++;
  int i,total[items]; //replaced fixed value with variable to prevent excessive empty rows from printing
  printf("Country  Females  Males  Total\n");
  for(i=0;i<items;i++){
  total[i]=data[i]->females+data[i]->males;
  printf("%15s  %7i  %7i  %8i\n",data[i]->country,data[i]->females,data[i]->males,total[i]);
  }
}


int main(){

  FILE *eduData=fopen("SecondaryEd2005.txt","r");
  if(eduData==NULL){
  printf("File not found.");
  exit(1);
  }
  printf("File opened successfully.\n");

  int k,fscanret;
  person_count* data[159]; //added 1 to prevent out of bounds memory access

  for(k=0;k<158;k++){
data[k]=malloc(sizeof(person_count));
fscanret=fscanf(eduData,"%s %i %i\n",data[k]->country,&data[k]->females,&data[k]->males);
if (fscanret==EOF){ //check return value to avoid going past end of file
  free(data[k]); //discard empty record and free memory if EOF reached
  k--;
  break;
}
printf("%s %i %i\n",data[k]->country,data[k]->females,data[k]->males);
  }
  fclose(eduData);

  printTable(data,k); //print k number of entries.

  while (k>=0){
free(data[k]); //free memory for all entries. DONT FORGET THIS
k--;
  }

  return 0;
}
#包括
#包括
类型定义结构{
char country[20];//已修复以更好地反映国家字段
智力女性;
智力男性;
}人数;;
作废打印表(人员计数*数据[],整数项){
项目++;
int i,total[items];//将固定值替换为变量,以防止打印过多的空行
printf(“国家/地区女性/男性总数”);
对于(i=0;ifemales+数据[i]>雄性;
printf(“%15s%7i%7i%8i\n”,数据[i]>国家,数据[i]>女性,数据[i]>男性,总数[i]);
}
}
int main(){
文件*eduData=fopen(“SecondaryEd2005.txt”,“r”);
if(eduData==NULL){
printf(“未找到文件”);
出口(1);
}
printf(“文件已成功打开。\n”);
int k,fscanret;
person_count*data[159];//添加1以防止越界内存访问
对于(k=0;k国家,&data[k]>女性,&data[k]>男性);
如果(fscanret==EOF){//请检查返回值以避免超过文件的结尾
释放(数据[k]);//如果达到EOF,则丢弃空记录并释放内存
k--;
打破
}
printf(“%s%i%i\n”,数据[k]->国家,数据[k]->女性,数据[k]->男性);
}
fclose(教育数据);
printTable(数据,k);//打印k个条目。
而(k>=0){
释放(数据[k]);//为所有条目释放内存。别忘了这一点
k--;
}
返回0;
}

data[k]->country=place
-该缓冲区再次用于下一个条目(以及下一个条目等),每次作为
place[]悬空
在每次迭代中到达for循环范围后将丢失。输入文件中的任何国家/地区是否超过19个字符?是的,确实存在大小为25左右的国家/地区。谢谢,我更改了位置的大小[]到30,程序运行。但是,printTable只打印一个国家,即文件中的最后一个国家。我想WhozCraig对此做了一些说明。我如何更改它?谢谢。但是是否可以使用*国家指针,因为在任务中它被声明为应该是指针?如果要将其用作指针,则需要将其设置为指向固定的全局字符数组或指向已分配内存的指针。在这两种情况下,我认为通过将country声明为指针,处理器需要做更多的工作才能完成任务。谢谢,我尝试了您和其他人建议的更改-释放内存,更改“country”用于数组类型和其他内容。现在程序完全运行。但我想我会尝试使用国家指针来检查。谢谢,尼古拉斯。我将“国家”更改为数组类型,并应用了Mike建议的更改。现在程序运行良好。唯一的问题是为什么一些输出条目看起来像:“British_Virgin_Islanê1020 862 1882”(国家/地区条目包括一些奇怪的符号和方框)?由于您是以字符形式存储字母,因此只有8位,因此有255种可能。如果您的文本文件包含特殊字符,则可能使用2个字节,它们将显示为2个字符。如果您要处理特殊字符,则应了解ascii和utf-8。