0

我不知道为什么第一个fwrite()for customer, 有效,但不是第二个fwrite()for 消息的符号。我的程序想要检查客户和消息中的符号是否已包含在库中.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

4 回答 4

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 调用并修复它们

于 2012-12-03T07:27:27.690 回答
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(), GetLastIdx2(), SetSymbol(), SetAlphabet(),Search_symbol()

D)以下(我假设是)全局变量和数据结构没有定义:Customer_history, TabInt, temp, CC, list_symbol,tempalfabet

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

所以根据我所拥有的,这里有一些输入:

1)你正在读入你的list_symbol,这应该是一个指向一个足够大的内存块的指针52*sizeof(Ssymbol),这应该是大约 1092 字节。

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

另请注意,如果list_symbol是一个Ssymbols 数组,那么您的读取代码会因为您的结构中有一个数组而被搞砸,它将逐字节读取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);

让我们说“test.txt”里面有:

C abcdefghijklmn
3 12345678

然后你的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'

这可能不是你想做的。确保您的数据与您的结构匹配!

2)您scanf()完全显示的错误:

char tempc;
...
scanf("%s", &tempc);

如果你想要一个字符,你想要“%c”,而不是“%s”。我没有看到上面的其他声明(参见 D 点),但是根据您的打印和使用情况,我可以告诉您tempalfabet并且CC几乎可以肯定也是错误的。

3)scanf()除非您使用它们,否则您的 s 将留下换行符:

printf("Please input new symbol:");
scanf("%c\\n", &tempc);  // <-- escaped newline will do that for you

4) 你用“wb+”打开你的文件。请参阅用于写入和附加到二进制文件的fopen() 选项。如果你想要一个二进制文件来读写你需要:“ab+”,如果你想要一个文本文件“a+”就可以了。

5)您不重置文件指针:

fopen(file for reading, writing, and appending);
fread(stuff);
do c code;
fwrite(stuff);

这将导致您编写的内容被附加到文件的底部。我不知道那是不是你想要的。因此,如果您想读取完整list_symbol的数据,然后将新数据集附加到文件底部,这可能不是问题。我怀疑您想覆盖文件中的内容......在这种情况下,您需要fseek()回到开头,或者您可以简单地关闭并打开文件。

于 2012-12-05T16:10:22.333 回答
0

I am trying to guess the issue, since the entire code is not vailable..

Is it possible that the number of symbols is exceeding 52, and you are writing only first 52 symbols? So fwrite is indeed working, but it is not changing the data file. Try printf'ing i(=GetLastIdx2), to see if it is exceeding 52.

Also, instead of having array for list_symbols, I would recommend using a linked list & fread/fwrite, using a while loop, to read/write all the symbols in the data file.

于 2012-12-01T15:46:21.140 回答
0

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

然后你应该使用“rb+”模式打开文件,而不是“wb+”,它会截断整个数据。在 "wb+" 模式下,文件数据被截断并且fread()应该返回 0,整个 do/while 变得无效。

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

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

于 2012-12-03T06:36:15.773 回答