奇怪的字符保存在我的文本文件中

时间:2017-10-04 13:32:26

标签: c file text input

我试图创建一个可以在文本文件中存储某些信息的程序。我遇到的问题是,到目前为止我写的代码中存储的信息是一堆奇怪的符号和字符。我设法找到它发生的地方,但我似乎无法解决它。看起来在我的register_item函数中,项目编号和余额由于某种原因得到了奇怪的值。如果有人能看到我犯了什么错误,那将不胜感激。

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

    #define MAX 20

    struct vara
    {
        int itemnumber[20];
        char name[30];
        int balance[20];
    };

    open_file(FILE *ange_filnamn, char filnamn[], struct vara varor[], int *antal_varor)
    {
        int mainmenu = 0;
        while (mainmenu != 1 && mainmenu != 2)
        {
            printf("Do you want to open an existing file (1) or create a new one (2)?\n");
            scanf("%d", &mainmenu);
            //system("CLS");
            if(mainmenu==1)
            {
                printf("Choose filename (ex. .txt).\n");
                scanf("%s", filnamn);
                ange_filnamn=fopen(filnamn, "r+");         

                while(!feof(ange_filnamn))
                {

                    fread(&varor[*antal_varor], sizeof(struct vara), 1, ange_filnamn);
                    if(!feof(ange_filnamn))
                    {
                        *antal_varor=*antal_varor + 1;        
                    }
                }
                printf("\nNumber of items: %d \n",*antal_varor);
                fclose(ange_filnamn);              
            }

            if(mainmenu==2)
            {
                printf("What name do you want for your new file?\n");
                scanf("%s", filnamn);
                ange_filnamn=fopen(filnamn, "w+");
                printf("File is created!\n");
                *antal_varor = 0;                 
                fclose(ange_filnamn);               
            }
        }
    }

    register_item(struct vara *varor, int *antal_varor)
    {
        printf("Item number:\n");                             
        scanf("%d", varor[*antal_varor].itemnumber);    
        printf("Name:\n");
        scanf("%s", varor[*antal_varor].name);
        printf("Balance:\n");
        scanf("%d", varor[*antal_varor].balance);   
        *antal_varor+=1;
    }

    print_item(struct vara varor[], int antal_varor)
    {
        int i;
        for (i=0; i < antal_varor; i++)
        {
            printf("%d. Item number: %d Name: %s Balance: %d\n", i, varor[i].itemnumber, varor[i].name, varor[i].balance);         
        }
    }

    quit_program(char filnamn[], struct vara varor[], int *antal_varor)
    {
        FILE *fil;
        //printf("%s", filnamn);
        fil=fopen(filnamn, "w+");                                             
        fwrite(varor, sizeof(struct vara), *antal_varor, fil);
        fclose(fil);
    }

    int main(void)
    {
        FILE *ange_filnamn;
        struct vara varor[MAX];
        int mainmenu, menu, antal_varor=0;
        char filnamn[20], filen[30]; 

        open_file(ange_filnamn,filnamn, varor, &antal_varor);

        //Second menu
        while(menu!=7)
        {
            printf("\n");
            printf("1. Register new items to inventory.\n");
            printf("2. Print all items from inventory.\n");
            printf("3. Search for item.\n");
            printf("4. Change inventory.\n");
            printf("5. Sort inventory.\n");
            printf("6. Deregister item from inventory.\n");
            printf("7. Quit.\n");
            scanf("%d", &menu);

            if(menu==1)
            {
                register_item(varor, &antal_varor);
            }

            if (menu==2)
            {
               print_item(varor, antal_varor); 
            }

            if (menu==3)
            {
                printf("test");
            }

            if (menu==4)
            {
                printf("test");
            }

            if (menu==5)
            {
                printf("test");
            }

            if(menu==6)
            {
                printf("test");
            }
            if (menu==7)
            {
                quit_program(filnamn, varor, &antal_varor);
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

你有一系列结构。该数组包含antal_varor个结构,每个结构包含成员(元素)itemnumbernamebalance

在我们开始之前,请注意一点:我认为您的结构定义有一些错误。根据您使用它的方式,我认为您想要

struct vara
{
    int itemnumber;
    char name[30];
    int balance;
};

但你的问题是关于编写文件。当你打电话

fwrite(varor, sizeof(struct vara), *antal_varor, fil);

你正在写出整个数组,一次性地在&#34;二进制&#34;中,这就是你无法读取的原因。如果你想用更易读的形式写出来,你可以做这样的事情。在这里,我有一个关于数组元素的显式循环,每次循环,我打印出该元素的所有成员:

int i;
for(i = 0; i < *antal_varor; i++ {
    fprintf(fil, "varor %d:\n", i);
    fprintf(fil, " itemnumber: %d\n", varor[i].itemnumber);
    fprintf(fil, " name: %s\n", varor[i].name);
    fprintf(fil, " balance: %d\n", varor[i].balance);
}

所以,首先尝试一下。您应该会发现输出文件非常易读。

现在,问题在于,因为您以这种更好,更易读的格式编写了文件,您的代码将数据读回来,以前用过

fread(&varor[*antal_varor], sizeof(struct vara), 1, ange_filnamn);

不再适用了。但是这里有一些你可以用来读回新格式文件的代码。这段代码用fgets逐行读取文件,弄清楚每行是什么,然后逐个插入数据项<{1}}数组重建它。

varor

我还没有对此进行测试,所以可能会有一些小错误,但它应该会给你这个想法。

(还有更好的方式来编写这类东西,但它们更复杂或需要更多的基础设施,所以我坚持一些非常简单和易懂的东西,尽管它已经过去了。不太健壮。)

答案 1 :(得分:0)

你问题的评论者是对的。
- printf显示的内容(并使用fprintf写入文件)是数字的ASCII表示 - 存储在存储器中(并用fwrite写入)是实际的“二进制”值 在C中,无论存储的值如何,int变量始终占用内存中相同的字节数。这就是你的sizeof()一致工作的原因。读写能够始终如一。

(请注意,并非所有C实现都使用相同大小的int。在我现在使用的x86 Linux中它是4个字节)。

显示ASCII表示时,所需的ASCII数字字符数取决于值。因此,如果读取的值已经以这种方式存储,则必须“解析”文本并从读取的数字中构建整数值,并且通常将是可变数字的数字。 (这就是scanf所做的。)因此,读取和解析ASCII可能被认为比读取存储为二进制int的值更复杂,该值总是相同的大小。

重要提示:如果您要将文件读取为二进制文件,则应使用“b”属性将其打开,如下所示:

ange_filnamn=fopen(filnamn, "r+b");

相似,打开二进制写:

fil=fopen(filnamn, "w+b");