C程序停滞不前

时间:2014-06-03 10:49:34

标签: c file typedef

对于C中的文件和记录,我有点新,而且我正在处理一个项目。以下程序必须为用户提供编辑,添加,删除和查看文件中所有记录的选项。

#include <stdio.h>

typedef struct {
    int code;
    char description[100];
    int volume;
} product;

void addition(FILE *filePtr);
void removal(FILE *filePtr);
void showcase(FILE *filePtr);
void edit(FILE *filePtr);
void description(FILE *filePtr);

int main() {
    int pick, i;
    product p = { 0, "", 0 };
    FILE *filePtr;
    if ( ( filePtr = fopen( "stock.dat", "a+") ) == NULL ) {
        printf("The file could not be read");
    } else {
        for( i = 0; i < 100; i++ )
                fwrite( &p, sizeof(p) , 1 , filePtr) ;
        fclose(filePtr) ;


        while ( !feof( filePtr)) {
            printf("    ************ MAIN MENU ************\n");
            printf("  ** -------------welcome------------- **\n");
            printf(" **                                      ** \n");
            printf("*  Please select one of the commands below *\n");
            printf("********************************************\n");
            printf("* Press 1 to remove products from the list *\n");
            printf("* Press 2 to change a product's quantity   *\n");
            printf("* Press 3 to add a new product to the list *\n");
            printf("* Press 4 to view product list             *\n");
            printf("* Press 5 to change a product's description*\n");
            printf("********************************************\n");
            scanf("%d", &pick);

            switch ( pick ) {
            case 1:
                removal(filePtr);
                break;
            case 2:
                edit(filePtr);
                break;
            case 3:
                addition(filePtr);
                break;
            case 4:
                showcase(filePtr);
                break;
            case 5:
                description(filePtr);
                break;
            default:
                printf("Error! Please enter a correct number");
                break;
            }
        }
    }
    return 0;
}

void removal(FILE *cfPtr) {
    product p;
    int code, volume;
    product empty = { 0, "", 0 };
    cfPtr = fopen("stock.dat", "a");

    printf("\nYou are about to remove a product from the list\n");
    printf("Please type that product's code\n");
    scanf("%d", &code);
    fseek(cfPtr, (p.code - 1)*sizeof(p), SEEK_SET);
    fread(&p, sizeof(p), 1, cfPtr);

    if (code == 0) {
        printf("\nProduct code %d not found, please try again\n", &code);
    } else {
        printf("\nProduct found! Record is being deleted...");
        fseek(cfPtr, (p.code - 1)*sizeof(p), SEEK_SET);
        fwrite(&empty, sizeof(p), 1, cfPtr);
        printf("\nRecord succesfully deleted!\n");
    }
    fclose(cfPtr);
}

void addition(FILE *cfPtr) {
    product p;
    int code, quantity;

    printf("You are about to add a new product in the list\n");
    cfPtr = fopen("stock.dat", "a");
    printf("Please input the product's code that you wish to add\n");
    fscanf( stdin, "%d", &p.code);
    printf("Now input the available quantity of the product that is in stock\n");
    fscanf(stdin, "%d", &p.volume);

    fseek( cfPtr, (p.code - 1) * sizeof(p), SEEK_SET);
    fseek( cfPtr, (p.volume - 1) * sizeof(p), SEEK_SET);
    fwrite(&code, sizeof(p), 1, cfPtr);
    fwrite(&quantity, sizeof(p), 1, cfPtr);

    printf("\n\nThe Product with code %d and quantity of %d has been added succesfully\n\n", p.code, p.volume);
    fclose(cfPtr);
}

void showcase(FILE *cfPtr){
    product p;
    int i;

    cfPtr = fopen("stock.dat", "a");
    printf("\n\n\n               ****SHOWING ALL PRODUCTS****\n\n\n");
    printf("PRODUCT CODE                  QUANTITY IN STOCK");

    for (i=0; i=100; i++) {
        printf("\n%d", p.code);
        printf("                  %d\n", &p.volume);
    }
    fclose(cfPtr);
}

void edit(FILE *cfPtr){
    product p;
    int code, volume;

    cfPtr= fopen("stock.dat", "a");
    printf("\n\n\n\You are about to edit a product's quantity\n");
    printf("Please enter that product's code\n");
    scanf("%d", &code);

    while ( !feof( cfPtr)) {
        fseek(cfPtr, ( code - 1)*sizeof(p), SEEK_SET);
        fread( &code, sizeof(p), 1, cfPtr);
        if (code = p.code){
            printf("Product %d was found! current quantity: %d\n", &code, &p.volume);
            printf("Please enter the new quantity of the product\n");
            scanf("%d", &volume);

            fseek(cfPtr, ( volume - 1)*sizeof(p), SEEK_SET);
            fwrite( &p, sizeof(p), 1, cfPtr);

            printf("List has been updated, product %d has now %d units\n\n", &code, &volume);
            break;
        } else {
            printf("Product code %d was not found please try again", &code);
        }
    }
    fclose(cfPtr);
}

void description(FILE *cfPtr) {
    product p;
    char desc;
    int i, code, check=0;

    cfPtr= fopen("stock.dat", "a");

    printf("\n You are about to change a product's description\n");
    printf("Please enter the product's code");

    scanf("%d", &code);

    for (i=0; i=100; i++) {
        fseek( cfPtr, (code -1)*sizeof(p), SEEK_SET);
        fread( &code, sizeof(p), 1, cfPtr);
        if (code = p.code) {
            printf("\nCode found, now please enter the description");
            scanf("%c", &desc);
            p.description[i] = 'desc';
            fwrite( &p, sizeof(p), 1, cfPtr);
            check = 1;
        }
    }

    if (check != 1){
        printf("Code not found! Please try again");
    }
}

这不是最终的代码,它肯定会有很多错误,但是我最关心的是以下代码行:

void showcase(FILE *cfPtr) {
    product p;
    int i;

    cfPtr = fopen("stock.dat", "a");
    printf("\n\n\n               ****SHOWING ALL PRODUCTS****\n\n\n");
    printf("PRODUCT CODE                  QUANTITY IN STOCK");

    for (i=0; i<100; i++) {  
        printf("\n%d", p.code);
        printf("                  %d\n", &p.volume);
    }
    fclose(cfPtr);
}

当此部分运行时,程序会一直运行并且不间断,显示无意义的记录。我已经为此工作了2天,我已经尽力研究,但是我自己找不到解决方案。再一次,我对此非常陌生,当然我的愚蠢错误可能会引起很多仇恨。无论如何,我会非常感谢我所做错的一些暗示,使程序无法正确保存记录并告诉他们。

提前致谢:)

更新 上述函数修复了一个小错误,但代码仍然无法保存新写入的记录..

3 个答案:

答案 0 :(得分:2)

for (i=0; i=100; i++) {

=是作业。在每次迭代之前,i会被赋值100

您想使用比较运算符,可能是<

for (i=0; i<100; i++) {

答案 1 :(得分:1)

 for (i=0; i=100; i++) {

 printf("\n%d", p.code);
 printf("                  %d\n", &p.volume);
 }

问题出在这里。 您可能打算键入for(i = 0 ; i < 100 ; i++),这样它就会循环100次 它现在做的实际上只是检查他是否可以将100的值放在i中,并且由于没有错误,因为他继续,在这种情况下它将是无限循环:P 另请注意,product p变量不会通过循环更改(甚至没有初始化),因此您基本上打印相同的值 - 而不仅仅是任何值,垃圾值(垃圾值是找到的)在该变量的内存中,因为没有变量在C中初始化为零,它们都从内存中的那个点获得一些垃圾值)100次:P 请记住这一点。

答案 2 :(得分:0)

对于每一行。

p.description[i] = 'desc';

错了。我不确定你要用这个做什么。我猜是要复制字符串&#34; desc&#34;进入描述char数组。这有两个问题。首先,您必须使用双引号来表示字符串文字,单引号表示字符文字,它只能是一个字符。区别在于&#34;&#34;还会分配一个NULL终止符来表示字符串的结尾。

e.g。

char* mystr = "This is my string"; 
char p = 'p';
char nullchar = '\0';

其次,您不能使用equals运算符将字符串分配给字符数组(除非您在循环中逐字符分配它)。您必须复制字符串。

strcpy(p.description, "desc");

请注意,对于其他字符串,您需要检查它们是否超出了数组的100个字符限制。您可以使用strncpy或snprintf来实现此目的。

另外,为什么要将文件指针传递给所有动作函数,然后在每个函数中再次打开文件?


此代码存在许多问题,我的建议是将所有输入的值保存在内存中,直到程序退出并且当时写入文件。如果您只是将其保存在内存中,则无需在每次添加后执行此操作。除非当然还有其他东西在读这个文件吗?

您还应该考虑保存文件的格式。您正尝试将结构本身写入文件中由用户输入决定的偏移量。如果有人输入了非常大的代码或音量值会怎样?

您可以考虑为您的产品考虑内存存储的链接列表,或者如果会有很多产品,则会在产品代码上编制索引的哈希表(使用C的缺点是这些东西不会出现在&#39 ; t作为语言的一部分)会更快。另一种选择是一个简单的数据库(sqlite),最后在写出文件时你可以考虑一种人类可读的格式,例如

<code> <description> <volume>

每个条目。 e.g。

1&#34;我的产品&#34; 10 2&#34;我的其他产品&#34; 25

当您的程序启动时,您解析文件并将其转换为内存表示,然后修改它,然后当您退出时回写更新的列表。