0

My code is supposed to find the product ID, name, quantity and price. When the product ID is entered, it should print the whole line where the product ID is located.

The text file contains this input:

1 CADBURY 999 1.900000
2 PEPSI 999 2.500000
3 IPHONE 976 2500.000000
4 SPIRULINA 100 50.000000

The code had been compiled with input of '4'. But the output was looping:

Please enter product ID :

It's not reading the whole line of '4'.

Here's the code:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>

int addProduct();

struct product
{
    int quantity, reorder, i, id;
    char name[20];
    float price;
};

int secondmain()
{
    FILE * fp;

    int i=0;
    struct product a;
    system("cls");

    char checker;



    do
    {
        fp = fopen("addproduct.txt","a+t");
        system("cls");

        printf("Enter product ID : ");
        scanf(" %d", &a.id);

        printf("Enter product name : ");
        scanf(" %s", a.name);

        printf("Enter product quantity : ");
        scanf(" %d", &a.quantity);

        printf("Enter product price : ");
        scanf(" %f", &a.price);


        fprintf(fp, "%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
        printf("Record saved!\n\n");

        fclose(fp);

        printf("Do you want to enter new product? Y / N : ");

        scanf(" %c", &checker);
        checker = toupper(checker);

        i++;

        system("cls");
    }
    while(checker=='Y');



    if(checker == 'N')
        {
        fp = fopen("addproduct.txt","r");

        while(fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price)==4)
            {
        fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price);
        printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
            }

        fclose(fp);

        }


return(0);
}

/*-------------- ERROR START HERE-----------------*/

int main()
{
FILE * fp;
system("cls");
struct product a;
char array[255];
int productID;

fp = fopen("addproduct.txt","r");

while(1){
fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price);

productID = atoi(array);

printf("Please enter product ID : ");
scanf(" %d", &productID);

if(productID == a.id)
    {
    fgets(array, 255, (FILE*)fp);
    printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);

    }

    }
return(0);
}
Jongware
  • 22,200
  • 8
  • 54
  • 100
Alif Khair
  • 87
  • 1
  • 1
  • 7
  • 1
    Please show the [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) because you have not shown the headers or `struct product`. Otherwise my first observation is that `productID = atoi(array);` is using an *uninitialised variable*. – Weather Vane Aug 14 '16 at 21:20
  • 3
    `if(a.id = productID)` : use `==` instead of `=` – BLUEPIXY Aug 14 '16 at 21:22
  • 2
    Compiler warnings are not for fun! Enable them and pay heed to them. Resolve the warnings before asking for help. – too honest for this site Aug 14 '16 at 21:24
  • 2
    Please check the function return values from `fopen`, `scanf` and `fgets` as a matter of habit. – Weather Vane Aug 14 '16 at 21:26
  • @WeatherVane sorry. Already edit the question. Ya, I want to ask whether the fgets can be change to something else. – Alif Khair Aug 14 '16 at 21:36
  • @BLUEPIXY Ya, I miss that. already edit. Now, the output is looping. – Alif Khair Aug 14 '16 at 21:36
  • @Olaf sorry, done clearing all the warning. – Alif Khair Aug 14 '16 at 21:36
  • Note that you read one line of input from the data file, then you ask the user for a product ID (then go back and read the next line of input from the file and ask for a new product ID, …). You should almost certainly read all the data from the file and only then ask for product ID values. You need to worry about EOF detection. Infinite loops are seldom a good idea IMO. See also [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) for one of the ways to avoid using (because it is always the wrong way to process the data). – Jonathan Leffler Aug 14 '16 at 21:56
  • a hint: you may want to first read in the data from the user, then open the file and add the record instead of opening the file and letting user enter values since in the former way you can do a check of the values before deciding whether to write to the file – AndersK Aug 14 '16 at 22:00
  • @AndersK. I already did that. but when I enter input, the program ends wihout any output. – Alif Khair Aug 14 '16 at 22:12
  • @JonathanLeffler Alright, I got it. I enter the input for couple of time. Then the output came out. Is there any reference for reading all the data file ? – Alif Khair Aug 14 '16 at 22:13
  • I'm not sure what you mean by 'is there a reference for reading all the data file'? There are lots of questions here on SO about reading a file into memory — you could look at those. Have you learned about dynamic memory allocation yet? If not, then you need a fixed size array of the structure and read into that, checking that you don't overflow the array. If you do want to handle dynamic memory allocation, there are many questions with answers about how to do so. – Jonathan Leffler Aug 14 '16 at 22:21

1 Answers1

1
while (fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price) == 4)
{
    fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price);
    printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
}

You are calling fscanf twice, it skips every 2nd line.

fgets(array, 255, (FILE*)fp);
printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);

This part is reading the line in to text. It should then use sscanf or strtok to parse line.

You may also have to flush stdin otherwise scanf(" %c", &checker) may not work. It makes things easier to break this up in to functions. Example:

int find_item_by_id(const char* fname, int find_id)
{
    int found = 0;
    struct product a;
    FILE *fp = fopen(fname, "r");
    if (fp)
    {
        while (fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price) == 4)
        {
            if (a.id == find_id)
            {
                found = 1;
                break;
            }
        }
        fclose(fp);
    }

    return found;
}

void add_item(const char* fname)
{
    struct product a;
    printf("Enter product ID : ");
    scanf(" %d", &a.id);

    printf("Enter product name : ");
    scanf(" %s", a.name);

    printf("Enter product quantity : ");
    scanf(" %d", &a.quantity);

    printf("Enter product price : ");
    scanf(" %f", &a.price);

    if (find_item_by_id(fname, a.id) != 0)
    {
        printf("item already exists\n");
        return;
    }

    FILE *fp = fopen(fname, "a+");
    if (fp)
    {
        fprintf(fp, "%d %s %d %.2f\n", a.id, a.name, a.quantity, a.price);
        fclose(fp);
    }
}

int main()
{
    const char* filename = "c:\\test\\_test.txt";

    printf("list:\n");
    struct product a;
    FILE *fp = fopen(filename, "r");
    if (fp)
    {
        while (fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price) == 4)
            printf("%d %s %d %f\n", a.id, a.name, a.quantity, a.price);
        fclose(fp);
    }

    while(1)
    {
        add_item(filename);

        printf("Add nother item? (y/n)\n");
        int result;
        while (1)
        {
            result = getchar();
            if (result == 'y' || result == 'n')
                break;
        }
        if (result != 'y')
            break;
    }

    return 0;
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77