简体   繁体   English

如何将特定行从二进制文件读取到结构C中

[英]How to read a specific line from binary file into a structure C

Essentially, I printed to a binary file using fseek() and fwrite(). 本质上,我使用fseek()和fwrite()打印到二进制文件。 However, I want to read the contents from a specific line into a structure. 但是,我想将特定行中的内容读入结构中。 I also used fseek() and fread() to obtain the contents. 我还使用了fseek()和fread()来获取内容。 I prompted the user to enter a code. 我提示用户输入代码。 From what I have learnt, I would use the value obtained from the user to use in the fseek function to get the specific line to start read from. 从我学到的知识中,我将使用从用户获得的值在fseek函数中使用以获取要开始读取的特定行。 Apparently, the fseek to read the contents does not work, I am getting gibberish essentially when it is displayed on the screen. 显然,无法快速读取内容,当它显示在屏幕上时,我基本上变得很乱。 Assistance is greatly appreciated. 非常感谢您的协助。

#include <conio.h>
#include <stdio.h> 


typedef struct registered
{
    int compcode;
    char compname[20];
    int pinID;
    int custID;
    char IDtype[15];
    int compID;
}REGISTERED;

void AddUpdate(REGISTERED info);
void SellPetrol();

void main(){
    REGISTERED info = {0, "Apple", 0, 0, "passport", 0};
    REGISTERED list;
    AddUpdate(info);
    SellPetrol();

}

void AddUpdate(REGISTERED info){
    int choice;


    FILE *registryfile = NULL;
    registryfile = fopen("Sales.dat", "ab");


    if (registryfile == NULL){
        perror("Error: ");
    }
    else{
        do{


            printf("Company Code: ");
            scanf("%d", &info.compcode);
            printf("Company Name: ");
            scanf("%s", &info.compname);
            printf("Pin: ");
            scanf("%d", &info.pinID);
            printf("Customer ID: ");
            scanf("%d", &info.custID);
            printf("ID type: ");
            scanf("%s", &info.IDtype);
            printf("Company ID: ");
            scanf("%d", &info.compID);  

            fseek(registryfile, (info.compcode - 1) * sizeof(REGISTERED), SEEK_SET);
            fwrite(&info, sizeof(REGISTERED), 1, registryfile); 


            printf("Enter choice: ");
            scanf("%d", &choice);
        }while(choice == 1);
    }
        printf("\tCompany Code: %d\t\n", info.compcode);
        printf("\tCustomer ID: %d\t\n", info.custID);
    fclose(registryfile);
}

void SellPetrol(){

    int code = 0, PIN;

    REGISTERED list;
    FILE *registryfile = NULL;
    registryfile = fopen("Sales.dat", "rb");

    if (registryfile == NULL){
        perror("Error: ");
    }
    else{

        printf("Please enter the company code: ");
        scanf("%d", &code);
    //  printf("Please enter the PIN: ");
    //  scanf("%d", &PIN);

        rewind(registryfile);
            fseek(registryfile, (code - 1) * sizeof(REGISTERED), SEEK_SET);
            fread(&list, sizeof(REGISTERED), 1, registryfile); //reads data into list

            fflush(stdin);  
            printf("Company Code: %d\n", list.compcode);
            printf("Company Name: %s\n", list.compname);
            printf("Pin: %d\n", list.pinID);
            printf("Customer ID: %d\n", list.custID);
            printf("ID Type: %s\n", list.IDtype);
            printf("Company ID: %d\n", list.compID);

    }
    fclose(registryfile);
}

It seems whichever method you're using to learn C is causing troubles, as the mistakes you seem to be making are common. 似乎您使用的任何一种学习C的方法都会引起麻烦,因为您似乎犯的错误很常见。 I suggest reading a book, such as K&R2E... Do the exercises as you stumble across them; 我建议阅读诸如K&R2E之类的书。 don't move on until you've completed them, and ask questions about them if necessary. 在完成它们之前不要继续前进,并在必要时询问有关它们的问题。


Don't fflush(stdin) . 不要fflush(stdin) fflush doesn't do what you think it does. fflush并没有按照您的想法做。


Check return values for functions such as fopen , scanf , fseek , fread , even fwrite . 检查函数fopenscanffseekfread甚至fwrite等函数的返回值 You'll probably find that your fread or scanf is returning a value indicating failure , hence the gibberish you speak of. 您可能会发现freadscanf 返回的值表示failure ,因此您所说的乱码


Be aware that C uses pass-by-value semantics ONLY . 请注意,C仅使用按值传递语义 The source of at least one error in your code is a misunderstanding regarding these semantics. 您的代码中至少一个错误的根源是对这些语义的误解。 Namely, AddUpdate has no way to modify the variable declared within main , as it recieves a copy of that variable; 也就是说, AddUpdate无法修改main内声明的变量,因为它收到了该变量的副本 at this point it seems void AddUpdate(REGISTERED info) should be void AddUpdate(void) and info should be declared within AddUpdate . 在这一点上, void AddUpdate(REGISTERED info)应该是void AddUpdate(void)并且应该在AddUpdate声明info


scanf("%s", &info.compname); probably doesn't do what you think it does. 可能没有按照您的想法去做。 The %s directive tells scanf to read (metalinguistically speaking) a word (that is, a whitespace-delimitered token), not a line (a newline delimitered token), of user input. %s指令告诉scanf读取(从语言上来说)用户输入的单词 (即,由空格分隔的标记),而不是一行 (由换行符分隔的标记)。 You probably want int x = scanf("%19[^\\n]", info.compname); 您可能需要int x = scanf("%19[^\\n]", info.compname); or better yet, char *x = fgets(info.compname, sizeof info.compname, stdin); 或者更好, char *x = fgets(info.compname, sizeof info.compname, stdin); ... ...


void main() is unportable , and so is #include <conio.h> . void main()是不可移植的#include <conio.h>也是如此。 You probably want int main(void) and ... you don't appear to be using any functions from <conio.h> , so you probably don't want anything in place of that. 您可能想要int main(void)和...您似乎并没有使用<conio.h>任何函数,因此您可能不想使用任何函数代替它。 In C99, a main function that has no return statement will implicitly return 0; 在C99中,没有return语句的main函数将隐式return 0;否则,它将return 0; without a warning issued. 没有发出警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM