标题:数据结构综合实验代码调试时出现很多问题
只看楼主
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
结帖率:80%
已结贴  问题点数:20 回复次数:9 
数据结构综合实验代码调试时出现很多问题
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct student
{
    char num[12];
    int math;
    int eng;
    int chi;
    int geo;
    int bio;
    int chem;
    int average;
}stu;/*学生信息链表结构体*/

typedef struct qnode
{
    int data;
    struct qnode *next;
}LQNode;/*队列链表节点结构体*/

typedef struct                                                                          
{
    LQNode *front;                                 
    LQNode *rear;                                  
}LQueue;/*链式队列结构体*/

void create_score(stu *s)/*成绩生成函数,利用rand函数生成学生六门学科的成绩*/
{ 
    s->math = rand()%101;
    s->eng = rand()%101;
    s->chi = rand()%101;
    s->geo = rand()%101;
    s->bio = rand()%101;
    s->chem = rand()%101;
}

int student_number_input_count(FILE *fp1,stu *c)/*从文件读取数据并统计*/
{
    FILE *fp2 = fp1;
    int amount = 0;
    while(!feof(fp2)){
        fscanf(fp2,"%s\n\b",c->num);     /*第一个问题!!!!!我不管用fgets 还是fscan函数读取文本最后一个数据时总是有时正确有时不正确*/
        create_score(c);
        amount++;
        c++;
    }
    printf("数据输入完毕!\n\n");
    return amount;
}

void score_average(stu *c,int *score,int numOFstudent)/*计算每个学生各学科的平均分,并存入数组中*/
{
    int *average = score,num = numOFstudent;
    stu *p = c;

    while(1){
        if(num == 0)
            break;
        *average = (p->math + p->eng + p->chi + p->geo + p->bio + p->chem)/6;
        p->average = *average;
        average++;
        p++;
        num--;
    }
}

void QueueInitiate(LQueue *Q)/*队列初始化函数*/
{
    Q->rear = NULL;
    Q->front = NULL;
}

void QueueAppend(LQueue *Q, int x)/*入队列函数*/
{
     LQNode *p = (LQNode *)malloc(sizeof(LQNode));
     if(p == NULL){
         printf("QueueAppend内存申请失败!!!\n");
     }

    p->data = x;
    p->next = NULL;
    
    if(Q->front == NULL)
        Q->front = p;
    else
        Q->rear->next = p;
    Q->rear = p;
    
}

int QueueNotEmpty(LQueue Q)/*队列为空判断函数*/
{
    if(Q.front == NULL) 
        return 0;
    else 
        return 1;
}

int QueueDelete(LQueue *Q,int *d)/*出队列函数*/
{
    LQNode *p;

    if(Q->front == NULL){
         printf ("队列已空无数据元素出队列! \n");
         return 0;
    }
    else{
      *d  = Q->front->data;
      p = Q->front;
      Q->front = Q->front->next;
      if(Q->front == NULL) Q->rear = NULL;
    }

      free(p);
      return 1;
}

void RadixSort(int *a,int n, int m,int d)/*基数排序函数*/
{
      int i, j, k, power = 1;
      LQueue *tub;
      tub = (LQueue *)malloc(sizeof (LQueue )* d);
      if(tub == NULL){
         printf("RadixSort内存申请失败!!!\n");
     }

      for(i = 0; i < d; i++)
          QueueInitiate(&tub[i]);                            
      for(i = 0; i < m; i++){
          if(i == 0)
              power = 1;
          else
                power = power *d;
          for(j = 0; j < n; j++){
              k = a[j] /power - (a[j] /(power * d)) * d;
              QueueAppend(&tub[k], a[j]);   
          }
          
          k = 0;
          for(j = 0; j < d; j++)
              while(QueueNotEmpty(tub[j]) != 0){
                  QueueDelete(&tub[j], &a[k]);
                  k++;
              }
      }
}

void ShellSort(int *a,int n,int d[],int numOfD)/*希尔排序函数*/
{
    int i, j, k, m, span; 
    int temp;

    for(m = 0; m < numOfD; m++){
        span = d[m];
        for(k = 0;k < span;k++){
            for(i = k; i < n-span; i = i+ span){ 
            temp = a[i+span];
            j = i;
            while(j > -1 && temp > a[j]){
                    a[j+ span] = a[j];
                    j = j- span;
            }
            a[j+ span] = temp;
            }
        }
    }
}

void CreatHeap (int *a, int n, int h)/*堆创建函数*/
{
    int i, j, flag;
    int temp;

    i = h;    
    j = 2*i+1;
    temp = a[i];
    flag = 0;

    while(j < n && flag != 1)
    {
        if(j < n-1 && a[j] > a[j+1])
            j++; 
        if(temp < a[j])
            flag = 1;
        else{
            a[i] = a[j];
            i = j;
            j = 2*i+1;
        }
        a[i] = temp;
    }
}

void InitCreatHeap(int *a,int n)/*堆初始化函数*/
{
    int i;
    for(i = (n-2)/2;i >= 0; i--)
        CreatHeap(a,n,i);
}

void Heapsort(int *a, int n)/*堆排序函数*/
{
    int i;
    int temp;
    InitCreatHeap(a, n);
    for(i = n-1; i > 0 ; i--)    
    { 
        temp = a[0]; 
        a[0] = a[i]; 
        a[i] = temp;
        CreatHeap(a, i, 0);
    }
}

void Quicksort (int *a, int low, int high)
{
    int i = low, j = high;
    int temp = a[low];

    while(i < j){
        while(i < j && temp >= a[j])
            j--;
        if(i < j){
            a[i] = a[j];
            i++;
        }
        while(i < j && a[i] > temp)
            i++;
        if(i < j){
            a[j] = a[i];
            j--;
        }
    }

    a[i] = temp;
    if(low < i)
        Quicksort(a, low, i-1);
    if(i < high)
        Quicksort (a, j+1, high);
}

void print(stu *a,int *b,int num)/*打印学生成绩以及班内学生平均分*/
{
    int count = num;
    stu *a1 = a;
    int *b1 = b;
    while(count > 0){
        printf("学号:%s  生物:%d  化学:%d  语文:%d  英语:%d  地理:%d  数学:%d  平均分:%d\n\n",a1->num,a1->bio,a1->chem,a1->chi,a1->eng,a1->geo,a1->math,a1->average);
        a1++;
        count--;
    }
    printf("平均分:");
    while(count < num){
        printf(" %d ",*b1);
        b1++;
        count++;
    }
    printf("\n\n");
}

void main()
{
     FILE *class1_data = fopen("e:\\student_name1.txt","r");
    FILE *class2_data = fopen("e:\\student_name2.txt","r");
    FILE *class3_data = fopen("e:\\student_name3.txt","r");
    FILE *class4_data = fopen("e:\\student_name4.txt","r");
    if(class1_data != NULL && class2_data != NULL && class3_data != NULL && class4_data != NULL){
            printf("Succeed to open file!\n");
    }
    else{
        printf("Failed to open file!\n");
    }
    stu *class1 = (stu *)calloc(sizeof(stu),1);                      /*班级学生信息链表*/
    int *class1_average = (int *)calloc(sizeof(int),1);             /*班级各学生平均分数组*/
    int class1_amount;                                             /*班级学生人数*/
    class1_amount = student_number_input_count(class1_data,class1);
    score_average(class1,class1_average,class1_amount);

    stu *class2 = (stu *)calloc(sizeof(stu),1);
    int *class2_average = (int *)calloc(sizeof(int),1);
    int class2_amount;
    class2_amount = student_number_input_count(class2_data,class2);
    score_average(class2,class2_average,class2_amount);

    stu *class3 = (stu *)calloc(sizeof(stu),1);
    int *class3_average = (int *)calloc(sizeof(int),1);
    int class3_amount;
    class3_amount = student_number_input_count(class3_data,class3);
    score_average(class3,class3_average,class3_amount);

    stu *class4 = (stu *)calloc(sizeof(stu),1);
    int *class4_average = (int *)calloc(sizeof(int),1);
    int class4_amount;
    class4_amount = student_number_input_count(class4_data,class4);
    score_average(class4,class4_average,class4_amount);

    

    double start, stop;              /*第四个问题!!!!!!!!!!  大概运行到这里是就会发生变量数值改变的情况*/
label:printf("****************************************************************\n");
    printf("1-快速排序  2-基数排序  3-堆排序  4-希尔排序  5-查看  0-退出程序");
    printf("\n****************************************************************\n\n");
    int select;
    int d[] = {1,3,6};
    printf("*********************************************\n");
    printf("               请输入功能序号:");
    scanf("%d",&select);
    printf("*********************************************\n");

    switch(select)
    {
    case 0:
        /*fclose(p1);fclose(p2);
        fclose(p3);fclose(p4);*/                  /*第二个问题!!!!!!!!!!!!!  fclose函数一用就触发断点*/
        exit(0);
    case 1:
        start = clock();
        Quicksort(class1_average,0,class1_amount-1);
        Quicksort(class2_average,0,class2_amount-1);
        Quicksort(class3_average,0,class3_amount-1);
        Quicksort(class4_average,0,class4_amount-1);
        stop = clock();
        printf("\n\n排序完成!用时:%lf毫秒\n\n",stop-start);start = 0;stop = 0;break;
    case 2:
        start = clock();
        RadixSort(class1_average,class1_amount,2,10);
        RadixSort(class2_average,class2_amount,2,10);
        RadixSort(class3_average,class3_amount,2,10);
        RadixSort(class4_average,class4_amount,2,10);
        stop = clock();
        printf("\n\n排序完成!用时:%lf毫秒\n\n",stop-start);
        start = 0;stop = 0;break;
    case 3:
        start = clock();
        Heapsort(class1_average,class1_amount);
        Heapsort(class2_average,class2_amount);
        Heapsort(class3_average,class3_amount);
        Heapsort(class4_average,class4_amount);
        stop = clock();
        printf("\n\n排序完成!用时:%lf毫秒\n\n",stop-start);
        start = 0;stop = 0;break;
    case 4:
        start = clock();
        ShellSort(class1_average,class1_amount,d,3);
        ShellSort(class2_average,class2_amount,d,3);
        ShellSort(class3_average,class3_amount,d,3);
        ShellSort(class4_average,class4_amount,d,3);
        stop = clock();
        printf("\n\n排序完成!用时:%lf毫秒\n\n",stop-start);
        start = 0;stop = 0;break;
    case 5:
        print(class1,class1_average,class1_amount);
        print(class2,class2_average,class2_amount);
        print(class3,class3_average,class3_amount);
        print(class4,class4_average,class4_amount);break;
    default:printf("输入错误,请重试");break;
    }
    system("pause");
    printf("/n");
    system("cls");
    goto label;
    
}


student_name1.txt (13 Bytes)
student_name2.txt (17 Bytes)
student_name3.txt (15 Bytes)
student_name4.txt (13 Bytes)


这些事数据文本,路径在e盘根目录下

我调试这段代码时发现很多不懂怎么解决的问题。编译器是vs2012

1.我不管用fgets 还是fscan函数读取文本最后一个数据时总是有时正确有时不正确
比如这个 “:”

2.fclose函数一用就会触发断点

3.启用调试时逐条语句运行时代码都能执行,但是开始执行(不调试)时程序直接就是没有提示的出错。


4.有些变量在代码运行过程中会自动改变,变成奇怪的值
比如这个

我目前逐句调试就发现这些问题,要是有哪里描述不清楚希望可以私信一下


[此贴子已经被作者于2020-10-19 23:55编辑过]

搜索更多相关主题的帖子: int stu temp 函数 printf 
2020-10-19 23:54
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:20 
代码太长,不看。
我不管用fgets 还是fscan函数读取文本最后一个数据时总是有时正确有时不正确
然后我搜索到用fscan的地方,是
while(!feof(fp2)){
        fscanf(fp2,"%s\n\b",c->num);     /*第一个问题!!!!!我不管用fgets 还是fscan函数读取文本最后一个数据时总是有时正确有时不正确*/
        create_score(c);
        amount++;
        c++;
    }

"%s\n\b" 是个啥玩意儿?循环也是错误的,!feof(fp2) 不表示接下来 fscanf 就能读成功。正确的做法是
while( fscanf读成功 )
    ……
if( feof(fp2) )
    发生了错误导致之前的读取循环中断;
2020-10-20 09:20
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
得分:0 
回复 2楼 rjsp
主要我的最后一行的数据他总是读不对
最后一行的14 总是读成其他东西, 我百度了fgets fscanf 说是每次读一行就把回车读进去啥的
2020-10-20 10:29
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 3楼 cabage
你看下面的代码运行对不对
程序代码:
#include <stdio.h>

int main( void )
{
    FILE* fp2 = fopen( "e:\\student_name1.txt", "r" );
    if( fp2 )
    {
        for( char num[12]; fscanf(fp2,"%s",num)==1; )
            puts( num );
        if( !feof(fp2) )
            puts( "在读取 fp2 时可能因为错误,或因为用户主动中止而未将文件读完." );
        fclose( fp2 );
    }
}

如上,这才是 feof 的正确用法。
2020-10-20 10:43
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
得分:0 
回复 4楼 rjsp
程序代码:
int student_number_input_count(FILE *fp2,stu *c)/*从文件读取数据并统计*/
{
    int amount = 0;
    if( fp2 )
    {
        for( c->num; fscanf(fp2,"%s",c->num)==1; ){           /*c->num, char[12]是学生结构体的学号*/
            create_score(c);
            puts( c->num );
                        amount++;
            c++;                                 
        }
        if( !feof(fp2) )
            puts( "在读取 fp2 时可能因为错误,或因为用户主动中止而未将文件读完." );
        fclose( fp2 );                                           /*触发断点*/
    }
    return amount;
}




我把你的新代码稍稍改成这样,结果就是这样,我不知道是不是我的stu *c才导致了问题出错,而且fclose也触发断点
2020-10-20 13:30
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
得分:0 
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct student
{
    char num[12];
    int math;
    int eng;
    int chi;
    int geo;
    int bio;
    int chem;
    int average;
}stu;/*学生信息链表结构体*/

void create_score(stu *s)/*成绩生成函数,利用rand函数生成学生六门学科的成绩*/
{ 
    s->math = rand()%101;
    s->eng = rand()%101;
    s->chi = rand()%101;
    s->geo = rand()%101;
    s->bio = rand()%101;
    s->chem = rand()%101;
}

int student_number_input_count(FILE *fp2,stu *c)/*从文件读取数据并统计*/
{
    int amount = 0;
    if( fp2 )
    {
        for( c->num; fscanf(fp2,"%s",c->num)==1; ){           /*c->num, char[12]是学生结构体的学号*/
            create_score(c);
            puts( c->num );
                        amount++;
            c++;                                 
        }
        if( !feof(fp2) )
            puts( "在读取 fp2 时可能因为错误,或因为用户主动中止而未将文件读完." );
        fclose( fp2 );                                           /*触发断点*/
    }
    return amount;
}

void score_average(stu *c,int *score,int numOFstudent)/*计算每个学生各学科的平均分,并存入数组中*/
{
    int *average = score,num = numOFstudent;
    stu *p = c;

    while(1){
        if(num == 0)
            break;
        *average = (p->math + p->eng + p->chi + p->geo + p->bio + p->chem)/6;
        p->average = *average;
        average++;
        p++;
        num--;
    }
}

void print(stu *a,int *b,int num)/*打印学生成绩以及班内学生平均分*/
{
    int count = num;
    stu *a1 = a;
    int *b1 = b;
    while(count > 0){
        printf("学号:%s  生物:%d  化学:%d  语文:%d  英语:%d  地理:%d  数学:%d  平均分:%d\n\n",a1->num,a1->bio,a1->chem,a1->chi,a1->eng,a1->geo,a1->math,a1->average);
        a1++;
        count--;
    }
    printf("平均分:");
    while(count < num){
        printf(" %d ",*b1);
        b1++;
        count++;
    }
    printf("\n\n");
}

void main()
{
     FILE *class1_data = fopen("e:\\student_name1.txt","r");
    FILE *class2_data = fopen("e:\\student_name2.txt","r");
    FILE *class3_data = fopen("e:\\student_name3.txt","r");
    FILE *class4_data = fopen("e:\\student_name4.txt","r");
    if(class1_data != NULL && class2_data != NULL && class3_data != NULL && class4_data != NULL){
            printf("Succeed to open file!\n");
    }
    else{
        printf("Failed to open file!\n");
    }
    stu *class1 = (stu *)calloc(sizeof(stu),1);                      /*班级学生信息链表*/
    int *class1_average = (int *)calloc(sizeof(int),1);             /*班级各学生平均分数组*/
    int class1_amount;                                             /*班级学生人数*/
    class1_amount = student_number_input_count(class1_data,class1);
    score_average(class1,class1_average,class1_amount);

    stu *class2 = (stu *)calloc(sizeof(stu),1);
    int *class2_average = (int *)calloc(sizeof(int),1);
    int class2_amount;
    class2_amount = student_number_input_count(class2_data,class2);
    score_average(class2,class2_average,class2_amount);

    stu *class3 = (stu *)calloc(sizeof(stu),1);
    int *class3_average = (int *)calloc(sizeof(int),1);
    int class3_amount;
    class3_amount = student_number_input_count(class3_data,class3);
    score_average(class3,class3_average,class3_amount);

    stu *class4 = (stu *)calloc(sizeof(stu),1);
    int *class4_average = (int *)calloc(sizeof(int),1);
    int class4_amount;
    class4_amount = student_number_input_count(class4_data,class4);
    score_average(class4,class4_average,class4_amount);

        print(class1,class1_average,class1_amount);
        print(class2,class2_average,class2_amount);
        print(class3,class3_average,class3_amount);
        print(class4,class4_average,class4_amount);
}


1楼代码精简版

[此贴子已经被作者于2020-10-20 13:45编辑过]

2020-10-20 13:36
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 5楼 cabage
单独运行4楼的代码有没有问题?
2020-10-20 13:43
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
得分:0 
回复 7楼 rjsp
没有问题 我改的就出现问题了
2020-10-20 13:44
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 8楼 cabage
你的代码乱七八糟的,上午我本想帮你改改,但实在是改不下去。
尤其是,你本意是想用“链表”,但子函数中却又当成“数组”来用,stu *class1 = (stu *)calloc(sizeof(stu),1); 等也只分配了一个长度,当成数组使用就越界了。
2020-10-20 14:18
cabage
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2020-4-15
得分:0 
回复 9楼 rjsp
多谢指点 原来是越界的事
2020-10-20 18:58



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-503540-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.295904 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved