简体   繁体   中英

Having trouble ints from a program reading file

Im working on a self-project where im trying to learn how to write and create files. Theres two problems. The first program should be writing information into a file, while the integers the user gives does copy into the file, the file is also giving illegible characters in the txt file its creating. The second issue is that when I compile program #2 it does not display the information entered from the txt file. (Sidenote: The libs I used were string, stdlib, stdio) This program is written in C

Program #1:

int main(void)
{
FILE *fp;
int pnum, quantity;
float price;
char num1[20];
char num2[20];
char num3[20];
char str[100] = "";
str[0] = '\0';

printf("This program stores a business inventory.\n");
fp = fopen( "inventory.txt" , "w" );

do
{
printf("Please enter item data (part number, quanitity, price): ");
scanf("%d, %d, %f", &pnum, &quantity, &price);

sprintf(num1, "%d", pnum);
sprintf(num2, "%d", quantity);
sprintf(num3, "%.1f", price);

strcat(str, num1);
strcat(str, " ");
if(pnum != 0)
{
    strcat(str, num2);
    strcat(str, " ");
    strcat(str, num3);
    strcat(str, " ");
}
else
{
strcat(str, num1);
strcat(str, " ");
strcat(str, num1);
strcat(str, " ");
strcat(str, num1);
strcat(str, " ");
}


}while( (pnum != 0));


fwrite(str , 1 , sizeof(str)+ 1 , fp);
fclose(fp);
printf("Thank you. Inventory stored in file inventory.txt.\n");

return 0;
}  

Program #2:

int main(void)
{
FILE * fp;
int pnum, quantity;
float price;

printf("Below are the items in your inventory\n");

printf("Part# Quantity Item Price\n");



fp = fopen("inventory.txt", "r");
rewind(fp);
do
{
fscanf(fp, "%d %d %f", &pnum, &quantity, &price);

printf("%5d", pnum);
printf("%9d", quantity);
printf("       $%.1f\n", price);

}while(pnum != 0);

return 0;
}

One of the key problems is that you don't make sure str is an empty string before you start, so you don't know what garbage is at the beginning of the output. Another is that you write the whole of str plus a byte that isn't part of str to the file, when you really only need to write the formatted data. Since fwrite() is required by the exercise, the code can continue to use that.

You should check inputs; you should check that files open; you should avoid buffer overflows.

Here's a first pass at the first program:

#include <stdio.h>
#include <string.h>

int main(void)
{
    FILE *fp;
    int pnum, quantity;
    float price;
    char num1[20];
    char num2[20];
    char num3[20];
    char str[100] = "";

    printf("This program stores a business inventory.\n");
    fp = fopen("inventory.txt", "w");

    do
    {
        printf("Please enter item data (part number, quantity, price): ");
        if (scanf("%d, %d, %f", &pnum, &quantity, &price) != 3)
        {
            pnum = 0;
            quantity = 0;
            price = 0.0;
        }

        sprintf(num1, "%d", pnum);
        sprintf(num2, "%d", quantity);
        sprintf(num3, "%.1f", price);

        strcat(str, num1);
        strcat(str, " ");
        if (pnum != 0)
        {
            strcat(str, num2);
            strcat(str, " ");
            strcat(str, num3);
            strcat(str, " ");
        }
        else
        {
            strcat(str, num1);
            strcat(str, " ");
            strcat(str, num1);
            strcat(str, " ");
            strcat(str, num1);
            strcat(str, " ");
        }
    } while (pnum != 0 && strlen(str) < sizeof(str) - 20);

    fwrite(str, 1, sizeof(str) + 1, fp);
    fclose(fp);
    printf("Thank you. Inventory stored in file inventory.txt.\n");

    return 0;
}

Given input file:

123, 45, 56.78
234, 56, 67.89
333, 77, 88.88
0, 234, 100.92

it produces the output file:

0x0000: 31 32 33 20 34 35 20 35 36 2E 38 20 32 33 34 20   123 45 56.8 234 
0x0010: 35 36 20 36 37 2E 39 20 33 33 33 20 37 37 20 38   56 67.9 333 77 8
0x0020: 38 2E 39 20 30 20 30 20 30 20 30 20 00 00 00 00   8.9 0 0 0 0 ....
0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
* (2)
0x0060: 00 00 00 00 01                                    .....
0x0065:

Note all the trailing null bytes.

A second pass simplifies the code by using snprintf() to format the line and then writes that with fwrite() — though it is very tempting to use just fprintf() to format and write.

#include <assert.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    const char filename[] = "inventory.txt";
    FILE *fp = fopen(filename, "w");

    if (fp == NULL)
    {
        fprintf(stderr, "Failed to open file %s for writing\n", filename);
        return 1;
    }
    printf("This program stores a business inventory.\n");

    int pnum, quantity;
    float price;
    do
    {
        printf("Please enter item data (part number, quantity, price): ");
        if (scanf("%d, %d, %f", &pnum, &quantity, &price) != 3 || pnum == 0)
        {
            pnum = 0;
            quantity = 0;
            price = 0.0;
        }
        char str[100];
        snprintf(str, sizeof(str), "%d %d %.2f\n", pnum, quantity, price);
        if (fwrite(str, sizeof(char), strlen(str), fp) != strlen(str))
            break;
    } while (pnum != 0);

    fclose(fp);
    printf("Thank you. Inventory stored in file %s\n", filename);

    return 0;
}

For the same input data, it produces the output:

0x0000: 31 32 33 20 34 35 20 35 36 2E 37 38 0A 32 33 34   123 45 56.78.234
0x0010: 20 35 36 20 36 37 2E 38 39 0A 33 33 33 20 37 37    56 67.89.333 77
0x0020: 20 38 38 2E 38 38 0A 30 20 30 20 30 2E 30 30 0A    88.88.0 0 0.00.
0x0030:

Or, as normal text:

123 45 56.78
234 56 67.89
333 77 88.88
0 0 0.00

Note there are no null bytes in the file at all.

A mildly revised reader program looks like:

#include <stdio.h>

int main(void)
{
    FILE *fp;
    int pnum, quantity;
    float price;

    printf("Below are the items in your inventory\n");

    printf("Part# Quantity Item Price\n");

    fp = fopen("inventory.txt", "r");
    //rewind(fp);
    do
    {
        if (fscanf(fp, "%d %d %f", &pnum, &quantity, &price) != 3)
            break;

        printf("%5d", pnum);
        printf("%9d", quantity);
        printf("       $%.1f\n", price);
    } while (pnum != 0);

    printf("All data read\n");

    return 0;
}

Given the outputs from the previous programs, it produces the same report from both versions of the data file:

Below are the items in your inventory
Part# Quantity Item Price
  123       45       $56.8
  234       56       $67.9
  333       77       $88.9
    0        0       $0.0
All data read

You could revise the second program to print all the data for each line of output in a single call to printf() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM