首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试从c/xcode中的文件中读取数字-仅获取零

尝试从c/xcode中的文件中读取数字-仅获取零
EN

Stack Overflow用户
提问于 2020-07-29 06:32:55
回答 1查看 66关注 0票数 1

我对C语言有点生疏,但我一直在开发一个需要从两个文件中读取并比较数值/做数学运算的程序。我尝试为每个文件创建一个结构,跳过前几行,因为它们包含字符串。然而,每当我尝试这样做的时候,我只能在结构中得到零。我不知道为什么这种事总是发生。我想可能是因为malloc和指针的问题。谢谢你的帮助。

另外,我会附上一个我正在阅读的文件的例子。

txt file

代码语言:javascript
复制
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
 
typedef struct fcat_s{
    float x;
    float y;
    float a_j2000;
    float b_j2000;
    float mag;
} fcat_s;
 
typedef struct cat_s{
    float num;
    float x;
    float y;
    float xworld;
    float yworld;
    float flux_auto;
    float mag_auto;
    float awin;
    float bwin;
} cat_s;
 
void readFCAT(FILE *fcat, fcat_s *f, int fcatcount){
    int i;
    for (i=0;i<(fcatcount);i++){
        if (i>5){
            fscanf(fcat, "%f", &f[i-5].x);
            fscanf(fcat, "%f", &f[i-5].y);
            fscanf(fcat, "%f", &f[i-5].a_j2000);
            fscanf(fcat, "%f", &f[i-5].b_j2000);
            fscanf(fcat, "%f", &f[i-5].mag);
        }
    }
}
 
void readCAT(FILE *cat, cat_s *c, int catcount){
    int j;
    for (j=0;j<(catcount);j++){
        if (j>9){
            fscanf(cat, "%f", &c[j-9].num);
            fscanf(cat, "%f", &c[j-9].x);
            fscanf(cat, "%f", &c[j-9].y);
            fscanf(cat, "%f", &c[j-9].xworld);
            fscanf(cat, "%f", &c[j-9].yworld);
            fscanf(cat, "%f", &c[j-9].flux_auto);
            fscanf(cat, "%f", &c[j-9].mag_auto);
            fscanf(cat, "%f", &c[j-9].awin);
            fscanf(cat, "%f", &c[j-9].bwin);
        }
    }
}
 
void printFCAT(fcat_s *f, int fcatcount){
    int i=0;
    for(i=0;(i<(fcatcount-5));i++){
        printf("%lf\t %lf\t %lf\t %lf\t %lf\n", f[i].x, f[i].y, f[i].a_j2000, f[i].b_j2000, f[i].mag);
    }
}
 
void printCAT(cat_s *c, int catcount){
    int i=0;
    for(i=0;(i<(catcount-9));i++){
        printf("%lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\n", c[i].num, c[i].x, c[i].y, c[i].xworld, c[i].yworld, c[i].flux_auto, c[i].mag_auto, c[i].awin, c[i].bwin);
    }
}
 
int main(void) {
 
    float exptime = 0;
    float F = 0;
    float Mi = 0;
    float Mcat = 0;
    float FLUX_AUTO = 0;
    float ZP = 0;
    char fcatname[50];
    char catname[50];
    int fcatcount = 0;
    int catcount = 0;
    char fcat_c;
    char cat_c;
    fcat_s *f;
    cat_s *c;
 
    printf("Please input the .fcat file name:\n");
    scanf("%str", fcatname);
     
    printf("Please input the .cat file name:\n");
    scanf("%str", catname);
 
    printf("Please input the exposure time:\n");
    scanf("%f", &exptime);
     
    FILE* fcat;
    fcat = fopen(fcatname, "r");
 
    if (fcat == NULL) {
        printf("The input file does not exist\n");
    }
    else {
        for (fcat_c = getc(fcat); fcat_c != EOF; fcat_c = getc(fcat)){
                if (fcat_c == '\n')
                    fcatcount++;
        }
    }
     
    FILE* cat;
       cat = fopen(catname, "r");
     
    if (cat == NULL) {
        printf("The input file does not exist\n");
    }
    else {
        for (cat_c = getc(cat); cat_c != EOF; cat_c = getc(cat)) {
                if (cat_c == '\n')
                    catcount++;
          //  printf("%c", cat_c);
        }
    }
     
    printf("\n");
    printf("The .fcat file has %d lines. \n", fcatcount);
    printf("The .cat file has %d lines. \n", catcount);
     
    printf("\n\n");
     
    f = (fcat_s*)malloc(fcatcount*sizeof(fcat_s));
    c = (cat_s*)malloc(catcount*sizeof(cat_s));
     
    rewind(fcat);
    rewind(cat);
     
    readFCAT(fcat, f, fcatcount);
    readCAT(cat, c, catcount);
     
    printf("FCAT CONTENTS\n");
    printFCAT(f, fcatcount);
     
    printf("\n\n");
     
    printf("CAT CONTENTS\n");
    printCAT(c, catcount);
     
    fclose(fcat);
    fclose(cat);
     
 
    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2020-07-29 10:59:46

您的链接txt文件指向jpg文件:(.如果您只在文本模式下发布文件中的几行实际内容,那么它将更加有用。所以我们可以把它复制到一个文本文件中。

返回到程序

  • 你可以使用fgets()feof()来计算行数,而不是调用fgetc(),这样每次调用只返回一行而不是一个字符,然后与你一次读取一个文件的newline
  • since进行比较你可以只使用一个缓冲区I =0;i<5;i+=1) fgets( FILE*
  • for(int,80,fcat);=0;i<5;i+=1将跳过这5行。
  • in main() 您应该将f声明为fcat_s**,并将c声明为cat_s**以便在函数中将其用作数组,正如在C
  • in readFCAT()和readCAT()中的argc/argv对中一样,您不需要传递行数:您已经使用它来分配正确数量的f和c结构,因此您可以一直读到文件末尾,它将返回一个值,您应该使用它。函数中的代码可能如下所示:

代码语言:javascript
复制
    int _readFCAT( FILE* fcat, fcat_s* f)
    {   int i = 0;
        while (!feof(fcat)
        {
            int n = fscanf(
                fcat, "%f %f %f %f %f",
                f[i]->x,
                f[i]->y),
                f[i]->a_j2000,
                f[i]->b_j2000,
                f[i]->mag
                );
        if (n != 5) return -1; // should read every time 5
        i += 1; // next item
        };
        return 0;
    };

您可以使用单个fscanf()调用来使用一行,而不是每个字段一行

  • 常见的替代解决方案是使用Fcat_data* readFCAT(char* FileName);和类似以下

的结构

代码语言:javascript
复制
typedef struct
{
    float x;
    float y;
    float a_j2000;
    float b_j2000;
    float mag;
}   Fcat_s;

typedef struct
{
    unsigned count;
    Fcat_s** f;
}   Fcat_data;

Fcat_data* readFCAT(char*);

就像每个C程序对argc/argv所做的那样。这样,您就让readFCAT()完成它们的工作,并返回一个填充的Fcat_data结构,其中包含一个数组f,用于从文件中读取的count元素的指针。封装它会让你在将来改变事情时有更多的自由。

由于我今天有时间,我将添加一个

示例:考虑以下文件

代码语言:javascript
复制
1
2
3
4
5
44752.008   3317.1910   231.943325247   -3.856654423   11.54381
4476        3317.1910   231.943325247   -3.856654423   11.54382
4476.3762   3317.1910   231.943325247   -3.856654423   11.54383
4476.3756   3317.1910   231.943325247   -3.856654423   11.54385
4476.3762   3317.1910   231.943325247   -3.856654423   11.54386

下面的输出

代码语言:javascript
复制
        5 sets of values

44752.007813    3317.190918     231.943329      -3.856654       11.543810
4476.000000     3317.190918     231.943329      -3.856654       11.543820
4476.375977     3317.190918     231.943329      -3.856654       11.543830
4476.375488     3317.190918     231.943329      -3.856654       11.543850
4476.375977     3317.190918     231.943329      -3.856654       11.543860

        End of data

从这个程序中

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    float x;
    float y;
    float a_j2000;
    float b_j2000;
    float mag;
}   FCAT_s;

typedef struct
{
    unsigned count;
    FCAT_s** f;
}   FCAT_data;

FCAT_data*  freeFCAT(FCAT_data*); // clear data
unsigned    line_count(char*); 
int         printFCAT(FCAT_data*); // show
FCAT_data*  readFCAT(char*); // build struct

int main(int argc,char** argv)
{
    char fName[50];
    const char* dflt = "fcat.txt";
    strcpy(fName, dflt);
    if (argc > 1)
        strcpy(fName, argv[1]); // if provided, uses the command line argument
    FCAT_data* f_db = readFCAT(fName);
    if (f_db == NULL) return -1;
    printFCAT(f_db);
    f_db = freeFCAT(f_db);
    return 0;
};

FCAT_data* freeFCAT(FCAT_data* db)
{
    // clean up
    for (int i = 0; i < db->count; i += 1)
        free(db->f[i]); // free item i
    free (db); // free db
    return NULL; // to invalidate pointer
};

unsigned    line_count(char* file)
{   // returns the # of lines in f
    FILE* f;
    char buffer[80];
    f = fopen(file, "r");
    if (f == NULL) return 0; // could not open
    int l = 0;
    while (!feof(f))
    {   fgets(buffer, 80, f);
        l += 1;
    };
    return l;
};

int         printFCAT(FCAT_data* data)
{
    // just dumps data on the screen
    printf("\n\t%d sets of values\n\n", data->count);
    for (unsigned i = 0; i < data->count; i += 1)
        printf( "%lf\t%lf\t%lf\t%lf\t%lf\n",
            data->f[i]->x,
            data->f[i]->y,
            data->f[i]->a_j2000,
            data->f[i]->b_j2000,
            data->f[i]->mag);
    printf("\n\tEnd of data\n\n");
    return 0;
};

FCAT_data*  readFCAT(char* file_name)
{
    unsigned l = line_count(file_name);
    if (l < 6)
    {
        printf("No data in '%s'\n", file_name);
        return NULL;
    };
    FILE* in = fopen(file_name, "r");
    char buffer[50];
    if (in == NULL) return NULL; // ? could not open
    for (int i = 0; i < 5; i += 1) fgets(buffer, 50, in);
    // now file points to the start of the data points
    // tme to create the databas struct
    FCAT_data* db = (FCAT_data*)malloc(sizeof(FCAT_data));
    db->count = 0;
    db->f = (FCAT_s**)malloc((l - 5) * sizeof(FCAT_s*));
    // database allocated with space for all datapoints
    while (!feof(in))
    {
        FCAT_s* next = malloc(sizeof(FCAT_s));
        int n = fscanf(
            in, "%f %f %f %f %f",
            &next->x,
            &next->y,
            &next->a_j2000,
            &next->b_j2000,
            &next->mag
        );
        if (n != 5)
        {   // last line could have just a newline?
            fclose(in);
            return db;
        };
        db->f[db->count] = next;
        db->count += 1;
    };
    fclose(in);
    return db;
};

您可能会发现这种方法更容易。您可以在命令行上传递文件名,也可以使用缺省的"fcat.txt"

示例中的4函数

代码语言:javascript
复制
FCAT_data*  freeFCAT(FCAT_data*); // clear data
unsigned    line_count(char*); 
int         printFCAT(FCAT_data*); // show
FCAT_data*  readFCAT(char*); // build struct

没什么好说的:文件名在命令行上提供。你可以传递2个文件名加上曝光时间。一个函数从提供的文件构建数据库,并返回数据的地址。另一个将数据转储到屏幕上进行测试,另一个释放数据,另一个计算文件中的行数。

main()

代码语言:javascript
复制
int main(int argc,char** argv)
{
    char fName[50];
    const char* dflt = "fcat.txt";
    strcpy(fName, dflt);
    if (argc > 1)
        strcpy(fName, argv[1]); // if provided, uses the command line argument
    FCAT_data* f_db = readFCAT(fName);
    if (f_db == NULL) return -1;
    printFCAT(f_db);
    f_db = freeFCAT(f_db);
    return 0;
};

最低限度。这只是一个例子。从文件建立数据库,在屏幕上显示数据,释放内存并退出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63143739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档