将文件指针传递给函数,文件未正确读取

时间:2010-10-02 21:10:48

标签: c file-pointer

我认为我的代码问题是文件没有正确传递。输入是一个包含三行的文件 1 2 3; 4 5 6; 7 8 9; 并且输出是分段故障(核心转储),输出应该打印第一行1 2 3。

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

int getNum();
int getLine();
int getMatrix();
int det1();
int det2();
int det3();
int det4();
int det5();
int det6();


main(){
  FILE *infile;
    infile = fopen("matrix.txt","r");
  int line[6];
  int lineSize;
  int error;
  getLine(line,lineSize,infile);
  printf("%d %d\n", line[0],line[1]);
  fclose(infile);
}

/***********************************************
Name : getLine
Description : To get the line of numbers
Arguments :  infile - the file pointer with numbers inside
             line[]  - the line of numbers
             lineSize - size of line
Returns : 1   - If no errors were encountered
          2 - If END OF FILE was reached
          -1 if non number detected

*************************************************/
int getLine(int line[], int lineSize, FILE *infile){
  int value;
  int l;
  lineSize=0;

  while(value != '\n'){
    value=0;
    l=getNum(value,*infile);
    if (value==EOF){
      return(2);
    }
    line[lineSize]=value;
    lineSize++;
  }
  if (l == -1){
    return(-1);
  }
  return(1);

}


/***********************************************
Name : getNum
Description : To get the Next number from file
Arguments :  infile - the file with numbers inside
             value  - the value of number grabed
Returns : 1   - If no errors were encountered
          -1  - If letter or non number detected
*************************************************/
int getNum(int value, FILE *infile){

  int c;
  int error=1;

  while ((c=getc(infile)) != EOF){
    if (c=='\n'){
      value = '\n';
      return(1);
    }
    if(c==32){//checking for space
      if (error == -1){
        return(-1);
      }
      else{
        return(1);
      }
    }
    else {
      value = 10*value + c - '0';
    }
    if((c<=47)||(c>=58)){
      printf("incorrect number input %d\n",c);
      error = -1;
    }
  }
  value = EOF;
  return(1);

}

3 个答案:

答案 0 :(得分:4)

略读代码......

int getNum();
int getLine();
int getMatrix();
int det1();
/* ... */

这些声明对编译器说:“嘿编译器,请注意我将使用这些名称调用函数(getNum,getLine,getMatrix,det1,...)并返回int,但我我没告诉你他们接受了什么参数。当我使用它们时,请相信我“

如果在将函数引入编译器时使用原型,那就更好了

int getNum(int value, FILE *infile);
int getLine(int line[], int lineSize, FILE *infile);
/* ... */

这些声明对编译器说:“嘿编译器,请注意我将使用这些名称调用函数,它们返回int并接受这些参数。如果我犯了错误,请抱怨让我知道我的错误“

...继续在main()

      /* ... */
      int lineSize;
      int error;
      getLine(line,lineSize,infile);
      /* ... */

您声明了lineSize但未提供变量值。当程序调用getLine时,lineSize的值几乎肯定是错误的值(甚至可能在调用函数之前使计算机崩溃)。在使用之前初始化(几乎)所有变量。

      /* ... */
      int lineSize = 0;
      int error = 0;
      getLine(line,lineSize,infile);
      /* ... */

我还没有撇去更多...

建议:提高编译器警告级别,并在编译产生警告时不运行程序。

答案 1 :(得分:3)

getLine()中,当您将infile FILE*提供给getNum()函数时,您可以取消引用它:

 l=getNum(value,*infile);

但是getNum()只会期望一个正常的FILE*,而不是一个被解除引用的infile。所以将 l=getNum(value,infile); 传递给该函数不变:

while(value != '\n')

此外,lines循环可能会永远运行,写入value数组的末尾,直到出现分段错误。控制何时循环终止的getNum()永远不会被修改(也不会被初始化,使其以任意值开始)。 value函数(可能应该修改value)获取作为参数传递的整数的副本,然后修改此副本。原始的value永远不会改变。

如果您希望函数更改value变量,则必须使用指向int getNum(int *value, ...) { *value = 5; ... } l=getNum(&value, infile); 的指针并用于修改该变量:

value

同样有点可疑的是'\n',一个整数变量,被分配并与'\n'(一个字符文字)进行比较。您确定要使用{{1}}的整数值作为循环的终止条件吗?

答案 2 :(得分:0)

虽然不是一个直接的答案,但我建议在随机点上贴上一些printf语句;这将让你相对快速地缩小崩溃的确切点。移动它们,直到你有两个printfs包围一行代码,然后你知道这些代码是崩溃的罪魁祸首,这将让你更好地进行诊断。