从程序读取文件

时间:2017-05-09 03:02:14

标签: c string file int scanf

我正在开发一个自我项目,我试图学习如何编写和创建文件。有两个问题。第一个程序应该是将信息写入文件,而用户提供的整数会复制到文件中,该文件还会在其创建的txt文件中提供难以识别的字符。第二个问题是,当我编译程序#2时,它不会显示从txt文件输入的信息。 (旁注:我使用的libs是字符串,stdlib,stdio)这个程序是用C语言写的

计划#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;
}  

计划#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;
}

1 个答案:

答案 0 :(得分:1)

其中一个关键问题是,在开始之前,你不确定str是一个空字符串,所以你不知道输出开头的垃圾是什么。另一个是当你真正只需要编写格式化数据时,你将整个str加上一个不属于str的字节写入文件。由于练习需要fwrite(),因此代码可以继续使用它。

你应该检查输入;你应该检查文件是否打开;你应该避免缓冲区溢出。

这是第一个项目的第一关:

#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;
}

给定输入文件:

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

它生成输出文件:

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:

注意所有尾随空字节。

第二遍通过使用snprintf()格式化行然后用fwrite()写入来简化代码 - 尽管使用fprintf()进行格式化和写入非常诱人。< / p>

#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;
}

对于相同的输入数据,它会产生输出:

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:

或者,正常文字:

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

注意文件中根本没有空字节。

温和修订的读者程序如下:

#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;
}

鉴于以前程序的输出,它从数据文件的两个版本生成相同的报告:

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

您可以修改第二个程序,通过一次调用printf()打印每行输出的所有数据。