C通过引用传递“返回”不正确的内容

时间:2014-11-19 12:41:10

标签: c parsing reference parameter-passing

我想使用函数从文件中读取一些值并将它们传递给main。 该文件具有特定格式:

  

string double char

例如2行:

  blahblah 0.12 G
     testtesttest 0.33 E

我有以下程序。虽然在功能中正确打印了值,但主要只打印了少数几个。其余的是0.00000,也没有打印字符。我究竟做错了什么?

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

int read_file(const char *filename, double **prob, char **sense);

int main(){

    double *iprob;
    char *sense;

    read_file("test.txt", &iprob, &sense);

    printf("Main: %lf %c\n", iprob[0], sense[0]);

    return 0;
}


int read_file(const char *filename, double **prob, char **sense){

    FILE *fp;
    char line[100], temp[80];
    int i = 0;

    fp = fopen(filename, "r");
    if (fp == NULL){
        fprintf(stderr,"File %s not found!\n", filename);
        return 0;
    }

    //*prob = (double *)malloc(sizeof(double) * 100);
    //*sense = (char *)malloc(sizeof(char) * 100);

    while( fgets(line, 100, fp) != NULL){

        prob[i] = (double *)malloc(sizeof(double));
        sense[i] =  (char *)malloc(sizeof(char));

        if ( sscanf(line, "%s %lf %c", temp, prob[i], sense[i]) < 3 ){

            fprintf(stderr, "Parsing error detected at line %d!", i);
            fclose(fp);
            return 0;
        }
        else{

            printf("%lf %c\n", *prob[i], *sense[i]);
        }
        i++;
    }
    fclose(fp);
    return 1;
}

2 个答案:

答案 0 :(得分:3)

你在函数中使用了一个指向double的双指针,因为你想要更新从main传入的指针。

问题是,分配的数组在*prob中,因此您必须将该数组的元素称为(*prob)[i]

*prob[i]*(prob[i])相同。 prob是指向指针的指针;它只有一个元素,可以这么说,所以除0之外的任何索引在这里都是无效的。

以下是对代码的更正:

  • 通过根据需要重新分配内存,读入与文件中一样多的条目。
  • 失败时返回-1,成功时返回项目数,因此您知道可以安全处理多少项目。
  • 使用后你应该free两个指针。

所以:

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

int read_file(const char *filename, double **prob, char **sense);

int main(){

    double *iprob = NULL;
    char *sense = NULL;
    int i, n;

    n = read_file("test.txt", &iprob, &sense);

    for (i = 0; i < n; i++) {
        printf("Main: %lf %c\n", iprob[i], sense[i]);
    }

    free(iprob);
    free(sense);

    return 0;
}

int read_file(const char *filename, double **prob, char **sense){

    FILE *fp;
    char line[100];
    int size = 0;
    int i = 0;

    *prob = NULL;
    *sense = NULL;

    fp = fopen(filename, "r");
    if (fp == NULL) return -1;

    while (fgets(line, sizeof(line), fp) != NULL) {
        char temp[80];

        if (i >= size) {
            size += 8;

            *prob = realloc(*prob, size * sizeof(**prob));
            *sense = realloc(*sense, size * sizeof(**sense));

            if (*prob == NULL || *sense == NULL) {
                fclose(fp);
                return -1;
            }
        }

        if (sscanf(line, "%79s %lf %c", temp, &(*prob)[i], &(*sense)[i]) < 3) {
            fprintf(stderr, "Parsing error detected at line %d!", i);
            fclose(fp);
            return -1;
        } 

        printf("%lf %c\n", (*prob)[i], (*sense)[i]);
        i++;
    }
    fclose(fp);

    return i;
}

答案 1 :(得分:0)

更改为

*prob = (double *)malloc(sizeof(double) * 100);
*sense = (char *)malloc(sizeof(char) * 100);

while( fgets(line, 100, fp) != NULL){

    //prob[i] = (double *)malloc(sizeof(double));
    //sense[i] =  (char *)malloc(sizeof(char));

    if ( sscanf(line, "%s %lf %c", temp, &(*prob)[i], &(*sense)[i]) < 3 ){

        fprintf(stderr, "Parsing error detected at line %d!", i);
        fclose(fp);
        return 0;
    }
    else{

        printf("%lf %c\n", (*prob)[i], (*sense)[i]);
    }
    i++;
}