分享
为什么问答平台  ›  专栏  ›  技术社区  ›  stellarCodeBro

如何在while循环中正确使用fscanf? - How to correctly use fscanf in a while loop?

  •  0
  • stellarCodeBro  · 技术社区  · 5 月前

    当我试图读取文本文件时,使用fscanf,zip_code_sample.txt无法正常工作。似乎fscanf没有做任何事情,因为当我尝试在以后打印变量时,我什么都没有得到。它甚至没有进入while循环。

    有人能帮我解决这个问题吗?我已经试着解决这个问题好几个小时了,在StackOverflow和许多在线文章上阅读了其他文章,但是没有一篇能帮助我解决这个问题。

    示例代码来自 zip_code_sample.txt :

    64720   Allenton
    63730   Annada
    64401   Alexandria
    64830   Anabel
    64402   Arbela
    

    源代码:

    #include <errno.h>
    #include <stdlib.h>   // For _MAX_PATH definition
    #include <stdio.h>
    #include <string.h>
    
    typedef struct cityStruct { unsigned int zip; char * town; } city;
    typedef struct zipTownsStruct {
        int * zips;      // indexes to main array cities sorted by zip
        city * * towns;  // pointers to main array cities sorted by town name
        city * cities;   // main array of cities in order from file not sorted
    } zipTowns;
    
    void getArrs(zipTowns * arrs, int size) {  
        if((arrs->zips = (int *) malloc(sizeof(int) * size)) == NULL) {
            fprintf(stderr, "%s\n", strerror(errno));
            exit(errno);
        }
        if((arrs->towns = (city **) malloc(sizeof(city*) * size)) == NULL) {
            fprintf(stderr, "%s\n", strerror(errno));
            exit(errno);
        }
        if((arrs->cities = (city *) malloc(sizeof(city) * size)) == NULL) {
            fprintf(stderr, "%s\n", strerror(errno));
            exit(errno);
        }
    }
    
    int getArgsInfoOpenFile(int argc, char * argv[], FILE ** infile, int * size) {
        int retval = 0;
        if(argc != 3) { // test for correct arguments number 3: exename, filename, size
            return -1;
        }
        if ((*infile = fopen("zip_code_sample.txt", "r")) == NULL) { // attempt to open file
            fprintf(stderr, "%s\n", strerror(errno));
            exit(errno);
        }
        return retval;
    }
    
    void readFile(zipTowns arrs, FILE * infile, int * length) {
        char * zip;
        char * town;
        while(fscanf(infile,"%s %s", zip, arrs.cities[*length].town) == 2) {
            arrs.cities[*length].zip = atoi(zip);
            printf("Zip: %s City: %s\n", arrs.cities[*length].zip, arrs.cities[*length].town); 
            printf("Zip: %s City: %s\n", zip, town); 
            length++;
        }
    }
    
    int main(int argc, char * argv[]) {
        zipTowns arrs; // all the arrays in one struct
        int length = 0; // current count of items in arrays 
        FILE * infile = NULL;
        int ret = 0, size = atoi(argv[2]);
        if(size > 999999 || size < 1) {
            printf("Illegal array size. Choose a size less than one million and greater than 0.\n");
            return -1;
        }
    
        if (getArgsInfoOpenFile(argc, argv, &infile, &size)) {
            printf("error in command line arguments\n");
            ret = -1;
        }else {
            getArrs(&arrs, size);
            readFile(arrs, infile, &length);
        }
        return 0;
    }
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   Jay    5 月前

    在函数中 readFile ,

    length++;
    

    应该是

    (*length)++;
    

    length++ 不会增加长度的值,相反,它会增加指针,导致指针指向错误的内存位置,并且所有的指针都应该从此处开始下降。

    其他问题:

    char * zip;
    char * town;
    

    你只有一个 char * . 您实际上应该为这些变量分配一些内存。

    typedef struct zipTownsStruct {
        int * zips;      // indexes to main array cities sorted by zip
        city * * towns;  // pointers to main array cities sorted by town name
        city * cities;   // main array of cities in order from file not sorted
    } zipTowns;
    

    不清楚你为什么 int *zip . 在下面的代码中,您只是分配 atoi 直接到这个变量。在这种情况下,它不应该是指针。