第一个fwrite工作但不是第二个

时间:2012-11-24 12:54:13

标签: c fwrite fread

我不知道为什么fwrite()的第一个customer有效,但不知道消息符号的第二个fwrite()。我的程序想要检查客户和消息中的符号是否已包含在库.dat中。这是我的代码:

typedef struct {
    char Name[50];
    int totalmsg;
    int totalword;
} Customer;

typedef struct {
    char symbol;
    char alphabet[20];
} Ssymbol;

void add_customer () {
    boolean found;
    int i;

    fp = fopen("customer.dat", "wb+"); 
    fread(&Customer_history, sizeof(TabInt), 102, fp);

    i = GetLastIdx(Customer_history);
    do {
        printf ("Please input customer's name: ");scanf("%s",&temp); 
        if (i == 0) {
            i++;
            SetName(&Customer_history,i,temp);
            SetMsg(&Customer_history,i,i);
            SetEff(&Customer_history,i);
            printf("Do you still wanna add another customer ?(Y/N)"); scanf("%s",&CC);
        }
        else {
            found = Search_name(Customer_history,temp);
            if (found == true) {
                printf("The name is already exist \n\n");
            }
            else {
                i++;
                SetName(&Customer_history,i,temp);
                    SetMsg(&Customer_history,i,i);
                    SetEff(&Customer_history,i);
            }
            printf("Do you still wanna add another customer ?(Y/N)"); scanf("%s",&CC);
        } 
    } while ((CC == 'y') || (CC =='Y'));
    fwrite(&Customer_history, sizeof(Customer), 102, fp);
    fclose(fp);
}

void add_symbol() {

    char tempc;
    char tempalphabet[20];
    boolean found;
    int i;

    fp = fopen("library.dat","wb+");

    fread(&list_symbol, sizeof(Ssymbol), 52, fp);

    i = GetLastIdx2(list_symbol);

    do{
        printf("Please input new symbol:");
        scanf("%s", &tempc);

        printf("Please input the alphabet of the symbol:");
        scanf("%s", &tempalfabet);

        if (i==0){
            i++;
            SetSymbol(&list_symbol,i,tempc);
            SetAlphabet(&list_symbol,i,tempalphabet);
            printf("Do you want to add another symbol? (Y/N)");
            scanf("%s",&CC);
        }      
        else{
            found = Search_symbol(list_symbol, tempc);
            if (found==true){
                printf("Symbol is already exist \n\n");
            }
            else{
                i++;
                SetSymbol(&list_symbol,i,tempc);
                SetAlphabet(&list_symbol,i,tempalphabet);
                printf("Do you want to add another symbol? (Y/N)");
                scanf("%s",&CC);
            }            
        }
    }

    while((CC=='y') || (CC=='Y'));

    fwrite(&list_symbol, sizeof(Ssymbol),52, fp);
    fclose(fp);
}

4 个答案:

答案 0 :(得分:4)

如果你只想要一个角色:

scanf("%s", &tempc);

然后将其更改为:

scanf("%c", &tempc);

否则,您需要将tempc定义为数组(并且不要使用&)。

此处,由于tou传递数组,因此不应使用address-of(&):

printf("Please input the alphabet of the symbol:");
// scanf("%s", &tempalfabet); is wrong
scanf("%s", tempalfabet); // correct

检查代码中的所有scanf调用并修复它们

答案 1 :(得分:2)

如果没有更多可编译的"很难说。您的代码版本......在这里为您提供一些观点:

A)boolean不是C中的类型。您需要以下内容:

#include <stdbool.h> // or some other header that defines bool
typedef bool boolean;

失败:

typedef int boolean;
#define false 0
#define true 1

B)add_customer()add_symbol()使用未定义的fp。您需要为这些操作定义FILE * fp

C)未定义以下(我假设为)方法:GetLastIdx()SetName()SetMsg()SetEff()Search_Name(),{{ 1}},GetLastIdx2()SetSymbol()SetAlphabet()

D)以下(我假设是)未定义全局变量和数据结构:Search_symbol()Customer_historyTabInttemp,{{1} },CC

根据你的问题描述,我假设你有这个工作,所以这些都应该被定义。如果您可以提供更完整,可编译的代码版本来显示问题,我可以提供更多帮助。

基于我所拥有的,这里有一些输入:

1)您正在读取list_symbol,这应该是指向一个足够tempalfabet的内存块的指针,这应该是1092字节左右。

list_symbol

另请注意,如果52*sizeof(Ssymbol)是一个fread(&list_symbol, sizeof(Ssymbol), 52, fp); 数组,那么您的阅读代码会被您的结构中有一个数组搞砸,list_symbol会读取并填充您的数据正好字节。例如:

Ssymbol

让我们说&#34; test.txt&#34;在其中:

fread()

然后您的Ssymbol list_symbol[52]; FILE * fp = fopen("test.txt", "r"); memset(list_symbol, 0, 52*sizeof(Ssymbol)); fread(list_symbol, sizeof(Ssymbol), 52, fp); 将如下所示:

C abcdefghijklmn
3 12345678

这可能不是你想要做的。确保您的数据符合您的结构!

2)你完全展示的list_symbol个错误:

list_symbol[0].symbol = 'C'
list_symbol[0].alphabet = ' abcdefghijklmn3 12' //note the newline and spaces fill it
list_symbol[1].symbol = '3'
list_symbol[1].alphabet = '45678'

你想要&#34;%c&#34;如果你想要一个角色,而不是&#34;%s&#34;。我没有看到上面的其他声明(请参阅D点),但根据您的打印件和我的使用情况,我可以告诉您scanf()char tempc; ... scanf("%s", &tempc); 几乎肯定也是错误的。

3)除非您使用换行符,否则tempalfabet将留下换行符:

CC

4)用&#34; wb +&#34;打开文件。有关编写和附加到二进制文件的信息,请参阅fopen() options。如果你想要一个二进制文件读写,你需要:&#34; ab +&#34;,如果你想要一个文本文件&#34; a +&#34;会做的。

5)您没有重置文件指针:

scanf()

这将导致您所写的内容被附加到文件的底部。 我不知道那是不是你想要的。因此,如果您想要读取完整的printf("Please input new symbol:"); scanf("%c\\n", &tempc); // <-- escaped newline will do that for you 数据,然后将新的一组添加到文件的底部,这可能不是问题。我 怀疑 您要覆盖文件中的内容但是...在这种情况下您需要fseek()回到开头,或者您可以简单地关闭并打开文件。

答案 2 :(得分:0)

我正在尝试猜测这个问题,因为整个代码都不可用。

符号数是否可能超过52,并且您只编写前52个符号?所以fwrite确实有效,但它并没有改变数据文件。尝试printf'ing i(= GetLastIdx2),看它是否超过52。

另外,我建议不要使用list_symbols数组,而是使用链接列表&amp; fread / fwrite,使用while循环,读/写数据文件中的所有符号。

答案 3 :(得分:0)

从代码逻辑中,它想要从文件中读取一些数据然后更新它。

然后你应该使用“rb +”模式打开文件,而不是截断整个数据的“wb +”。使用“wb +”模式时,文件数据将被截断,fread()应返回0,整个do / while将变为无效。

我不知道为什么第一个fwrite()有效,两者都不应该。

总之,请在ab+中尝试fopen()模式,并且在调用fseek()之前不要忘记使用SEEK_SET调用fwrite()来重置文件位置指示符,它可能会解决你的问题。