sscanf直到c

时间:2016-02-10 16:48:46

标签: c dynamic-memory-allocation file-handling scanf

我有一个C程序,它从文本文件中创建一个二进制文件。

/*makeBinry.c*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char *argv[]){
    char *ptext, *btext="file.bin";
    if(argc != 2){
        printf("Using default \"text.txt\" file to create mnemonics table\n");
        ptext = "text.txt";
    }else{
        ptext = argv[2];
    }

    FILE *fp, *fb;
    if(!(fp=fopen(ptext, "r"))){
        fprintf(stdout, "Error: File %s is not available\n", ptext);
        exit(1);
    }

    if(!(fb = fopen(btext, "wb"))){
        fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
        exit(1);
    }

    int i, j, k;
    char s[8], c, stringed[20];

    while(!feof(fp)){
        memset(stringed, '\0', sizeof(stringed));
        fscanf(fp, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
        sprintf(stringed, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
        fwrite(stringed, 1, strlen(stringed), fb);
    }
    fprintf(stdout, "Success: %s file successfully created\n", btext);

    fclose(fp);
    fclose(fb);
    return 0;
}

我有另一个程序读取二进制文件中的数据并存储到数组中。

/*mainProg.c*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

typedef struct opStruct{
    int hexv, fv, kv;
    char str[8], key;
} node;

node* makeTable(char *filename){
    FILE *fp;
    if(!(fp = fopen(filename, "rb"))){
        fprintf(stdout, "Error: Unable to open file %s\n", filename);
        exit(1);
    }
    int hv, fv, kv;
    char s[8], c, str[20];

    while(!(feof(fp))){
        sscanf(fp,"%X %d %c %d %[^\n]s", &hv, &fv, &c, &kv, str);
        fprintf(stdout, "%X %d %c %d %s", hv, fv, c, kv, str);
    }
    fclose(fp);
    return NULL;
}

int main(){
    int i;
    char *filename = "file.bin";
    node *t_table = makeTable(filename);
    return 0;
}

当我运行mainProg.c时,程序进入无限循环。我认为这是因为fp永远不会增加。我怎样才能增加文件指针并仍然使用sscanf以格式化的方式读取二进制文件?我不允许使用fread()。目前,由于我没有创建表格,因此makeTable函数会返回NULL

此外,由于二进制文件中的行数未知,如何使用realloc动态创建数组?

1 个答案:

答案 0 :(得分:0)

以下代码

  1. 正确处理错误情况
  2. 实际上生成二进制文件,而不仅仅是另一个文本文件
  3. 使用fscanf()的返回值,而不是错误的feof()
  4. 使用perror()因此系统错误消息显示在stderr
  5. 遵循公理:每行只有一个语句,并且(最多)每个语句一个变量声明
  6. 可以添加对fwrite(),fclose()的调用的错误检查,但它们不太可能产生错误

    现在是代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
        struct record
        {
            unsigned int hv;
            int fv;
            int kv;
            char c;
            char s[8];
        };
    
    int main(int argc, char *argv[])
    {
        char *ptext, *btext="file.bin";
        if(argc != 2)
        {
            printf("Using default \"text.txt\" file to create mnemonics table\n");
            ptext = "text.txt";
        }
    
        else
        {
            ptext = argv[1];
        }
    
        FILE *fp;
        FILE *fb;
    
        if(!(fp=fopen(ptext, "r")))
        {
            perror( "fopen for read of text file failed" );
            fprintf(stdout, "Error: File %s is not available\n", ptext);
            exit(1);
        }
    
        if(!(fb = fopen(btext, "wb")))
        {
            perror( "fopen for write of binary file failed" );
            fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
            fclose( fp ); // cleanup
            exit(1);
        }
    
        struct record myRecord;
    
        // produce binary file from text input
        // note: leading space in format string, to consume any left over newline, etc
        while(5 == fscanf(fp, " %X %d %c %d %7[^\n]",
                          &myRecord.hv,
                          &myRecord.fv,
                          &myRecord.c,
                          &myRecord.kv,
                          myRecord.s) )
        {
            fwrite( &myRecord, sizeof myRecord, 1, fb );
        }
    
        fprintf(stdout, "Success: %s file successfully created\n", btext);
    
        fclose(fp);
        fclose(fb);
        return 0;
    }
    
    
    
    /*mainProg.c*/
    #include <stdio.h>
    #include <stdlib.h>
    //#include <malloc.h>
    #include <string.h>
    
    //typedef struct opStruct
    //{
    //    int hexv, fv, kv;
    //    char str[8], key;
    //} node;
    
    struct record
    {
        unsigned int hv;
        int fv;
        int kv;
        char c;
        char s[8];
    };
    
    //node* makeTable(char *filename)
    void makeTable( char *filename )
    {
        FILE *fp;
        if(!(fp = fopen(filename, "rb")))
        {
            fprintf(stdout, "Error: Unable to open file %s\n", filename);
            exit(1);
        }
    
        // implied else, fopen successful
    
        struct record myRecord;
    
        // use fscanf() not sscanf()
        while( fread( &myRecord, sizeof myRecord, 1, fp) )
        {
            //sprintf( , "%X %d %c %d %s\n" hv, fv, c, kv, s );
            //fprintf(stdout, "%s", str );
            fprintf( stdout, "\n%X",   myRecord.hv  );
            fprintf( stdout, " %d",    myRecord.fv  );
            fprintf( stdout, " %c",    myRecord.c   );
            fprintf( stdout, " %d",    myRecord.kv  );
            fprintf( stdout, " %8.8s", myRecord.s   );
        }
        fprintf( stdout, "\n" ); // force flush
    
    
        fclose(fp);
        //return NULL;
    } // end function: makeTable
    
    
    int main( void )
    {
        //int i;
        char *filename = "file.bin";
        //node *t_table = makeTable(filename); // raises compiler warning about unused variable
        makeTable(filename);
        return 0;
    } // end function: main