【问题标题】:Problems when printing an array with pointers in C在 C 中打印带有指针的数组时出现问题
【发布时间】:2017-01-27 11:18:32
【问题描述】:

我是指针的新手,我正在尝试实现一个简单的代码,在其中我读取和写入一个数组,并且我还搜索两个给定索引之间的最小元素。 出于某种原因, write() 函数会打印大值(我猜它们是存储值的位置)。当我运行 poz_minVal 函数时,我也会收到一个 SIGSECV。 我知道这是一个小问题,但任何帮助都将不胜感激!

代码如下:

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

int read(int *v, FILE *f){
    int i,length;
    fscanf(f,"%d",&length);
    v = (int *)malloc(length*sizeof(int));
    for(i=0;i<length;++i)
        fscanf(f,"%d",v+i);
    return length;
}

void write(int *v, int length, FILE *g){
    int i;
    for(i=0;i<length;++i)
        fprintf(g,"%d ",*(v+i));
    fprintf(g,"\n\n");
}

int poz_valMin(int *v, int length,int left,int right){
    int k,mini = *v; //set mini as the 1st element in v
    for(k=left;k<right;++k)
        if(*(v+k) < mini)
            mini = *(v+k);
    return mini;
}

int main(){
    FILE *f = fopen("datein.txt","r");
    FILE *g = fopen("dateout.txt","w");
    int *v, n = read(v,f);
    write(v,n,g);
    fprintf("The minimum value between the indexes 2 and 4 is: %d.\n\n",poz_valMin(v,n,2,4));
    return 0;
}

【问题讨论】:

  • 请显示输入数据。
  • 哪一行?输入数据在哪里?
  • 你用指针弄错了!! :)
  • 你也忘了释放 v.
  • 写成v[i],而不是*(v+i),更容易也更惯用。

标签: c arrays pointers


【解决方案1】:

barak manos 所说的都是对的,但让我指出另一种定义读取函数的方法。

int * read(FILE *f){
   int *v,length;
   fscanf(f,"%d",&length);
   v = (int *)malloc(length*sizeof(int));
   for(i=0;i<length;++i)
       fscanf(f,"%d",v+i);
   return v;
}


然后在 main 你应该只写 v = read(f);
这看起来很干净并简化了理解。

提示:
一旦你注意到 write 正在产生垃圾,你应该打印数组 v,你可能已经发现了错误!

【讨论】:

【解决方案2】:

函数read应该取int** v,并赋值*v = ...

在函数内部更改输入参数不会影响函数外部该参数的值。

【讨论】:

    【解决方案3】:
    //int read(int *v, FILE *f) //<-- in this case v will be treated as local variable inside read() and not the parameter passed from main.
    int read(int **v, FILE *f)
    {
        int i,length;
        fscanf(f,"%d",&length);
        //v = (int *)malloc(length*sizeof(int));
        int *arr = (int *)malloc(length*sizeof(int));
        for(i=0;i<length;++i)
            //fscanf(f,"%d",v+i);
            fscanf(f,"%d",arr+i);
    
        *v = arr;  //now you are actually assigning the allocated memory to main::v
        return length;
    }
    
    read(&v,f);  //call read like this.
    
    【解决方案4】:

    以下代码:

    1. 将 cmets 纳入问题中,但良好的变量命名除外
    2. 干净编译
    3. 执行所需的操作
    4. 执行适当的错误检查

    您应该养成将main() 函数(在那些具有main() 函数的文件中)作为列出的第一个函数的习惯,然后对每个子函数使用适当的“原型”语句

    建议将size_t 用于绝对不能为负的值。

    #include <stdio.h>  // fopen(), fclose(),
    #include <stdlib.h>
    
    size_t read(       int **v, FILE *f);
    void   write(      int *v, size_t length, FILE *g );
    int    poz_valMin( int *v, int left, int right );
    
    
    int main( void )
    {
        FILE *f = fopen("datein.txt","r");
        if( !f )
        {
            perror( "fopen for read of datain.txt failed" );
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        FILE *g = fopen("dateout.txt","w");
        if( !g )
        {
            perror( "fopen for write to dataout.txt failed" );
            fclose( f ); // cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen for output successful
    
        int *v;
        size_t n = read(&v,f);
    
        write(v,n,g);
        fprintf( stdout,
                 "The minimum value between the indexes 2 and 4 is: %d.\n\n",
                 poz_valMin(v, 2, 4));
    
        free( v );
        fclose( f );
        fclose( g );
    }
    
    
    
    size_t read(int **v, FILE *f)
    {
        //int i;
        size_t length;
    
        if( 1 != fscanf(f,"%lu",&length) )
        {
            perror( "fscanf failed" );
            exit( EXIT_FAILURE );
        }
    
        // implied else, fscanf successful
    
        *v = malloc(length*sizeof(int));
        if( !v )
        {
            perror( "malloc failed" );
            fclose( f );
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        for(size_t i=0; i<length; ++i)
        {
            if( 1 != fscanf(f,"%d",(*v)+i) )
            {
                perror( "fscanf for array values failed" );
                free( *v );
                fclose( f );
                exit( EXIT_FAILURE );
            }
    
            // implied else, fscanf successful
        }
    
        return length;
    }
    
    
    void write(int *v, size_t length, FILE *g)
    {
        //int i;
    
        for( size_t i=0; i<length; ++i )
            fprintf(g,"%d ",*(v+i));
    
        fprintf(g,"\n\n");
    }
    
    
    int poz_valMin( int *v, int left, int right )
    {
        int k;
        int mini = *v; //set mini as the 1st element in v
    
        for(k=left; k<right; ++k)
            if(*(v+k) < mini)
                mini = *(v+k);
    
        return mini;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 2012-11-11
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      相关资源
      最近更新 更多