C:将文件作为参数传递

时间:2016-10-10 22:09:34

标签: c io

我无法将FILE指针作为参数传递给多个函数。

我想在main中打开文件,然后将其传递给一个函数,该函数会将一些内容写入其中,然后从该函数将其传递给另一个函数。我可以将它从main传递到第一个函数没问题,但是当我尝试将它传递给第二个函数时它有一个Segmentation错误。

我的代码看起来像这样:

void firstFunction(FILE*);
void secondFunction(FILE*);

int main(void) {
  FILE *fp;
  if((fp = fopen("test.txt", "ab+")) == 0) {
    return 1;
  }
  firstFunction(fp);
  return 0;
}

void firstFunction(FILE *fp) {
  fprintf(fp, "test");  /* Works */
  secondFunction(fp);   /* Causes Segmentation fault */
}

void secondFunction(FILE *fp) {
  /* never reaches here */
  fprintf(fp, "test2");
}

这很好地解释了我对此的看法。我尝试过传递各种不同的语法,例如secondFunction(* fp),但没有成功。

出了什么问题?从main到firstFunction但从first到secondFunction不是这样有效吗?

编辑:实际代码

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define LINESIZE 512

void runCommand(const char[], FILE*);
    void append(const char[], FILE*);

int main(int argc, char * argv[]) {
    char filename[LINESIZE];
    FILE *fp;
    char line[LINESIZE];

    sscanf(argv[1], "%s", filename);

    /* Open file for saving data */
    if((fp = fopen(filename, "ab+")) == 0) {
        perror("fopen");
        return 1;
    } else {    
        /* Reads lines from user */
        while(fgets(line, LINESIZE, stdin)){
            /* Omits empty lines */
            if(strlen(line) > 1) {
                runCommand(line, fp);
            }
        }
    }

    return 0;
}

/* Parses first word in input and executes proper command */
void runCommand(const char input[], FILE *fp) {
    char param1[LINESIZE];

    fprintf(fp, "test");
    append(input, fp);

    int r = sscanf(input, "%s", param1);

    if (!strcmp(param1, "append")){
        append(input, fp);
    } else {
        /* Error Handling */
    }   
}

void append(const char input[], FILE *fp) {
    char command[7];
    char fName[20];
    char lName[20];
    int score;

    int r = sscanf(input, "%s%s%s%d", command, fName, lName, score);

    if (r != 4) {
        /* Error Handling */
    }

    fprintf(fp, "%s%s%d", fName, lName, score);
}

1 个答案:

答案 0 :(得分:1)

int r = sscanf(input, "%s%s%s%d", command, fName, lName, &score);

你在sscanf的电话中通过了第56行的分数,但你应该传递它的地址。所以添加一个&符号:

testbc123testcd23cd23

之后,错误消失,test.txt读取如下:

void runCommand(const char[], FILE*);
    void append(const char[], FILE*);

在C中,函数的参数总是按值调用。因此,如果sscanf应该写入变量,传递变量没有帮助。你实际上必须传递它的地址,所以sscanf可以写入它。其他三个变量(command,fName和lName)不需要&符是因为在C中,您也无法传递数组。如果你试图传递一个数组,实际上你正在传递一个指向它的第一个元素的指针。所以函数原型

void runCommand(const char *, FILE*);
    void append(const char *, FILE*);

实际上是误导性的,因为它们的真正含义是:

runCommand: test
append: bc123
runCommand: test
append: cd23
append: cd23

在你对sscanf的调用中,数组“掉落”到指针(因此sscanf实际上可以写入其内容)。

/ edit:稍微修改过的代码,在fprintf语句中包含一些换行符(以及调用的注释),这是上面输入的输出:

handleClick = () => {
    this.setState({
        currentItem: this.value
    })
}