我不知道为什么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);
}
答案 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_history
,TabInt
,temp
,{{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()
来重置文件位置指示符,它可能会解决你的问题。