【问题标题】:How to read Texts/Numbers from a File in C如何从 C 中的文件中读取文本/数字
【发布时间】:2017-06-11 17:39:44
【问题描述】:

我有这段代码来写一个名为Phone Bill.txt的文件

#include<stdio.h>
int main(){
    FILE *file;
    file=fopen("Phone Bill.txt","w");

    if(file!=NULL){
        fprintf(file, "Number\t\tLocal Call Chargers\tInternational Call Charges\tRoaming Charges\n");
    }

    double phoneNumber; 
    float localCharges, internationalCharges, roamingCharges;
    char wantToContinue='Y';

    while(wantToContinue=='Y'){
        printf("Enter Phone Number: ");
        scanf("%lf",&phoneNumber);
        printf("Enter Local Call Charges: ");
        scanf("%f",&localCharges);
        printf("Enter International Call Charges: ");
        scanf("%f",&internationalCharges);
        printf("Enter Roaming Call Charges: ");
        scanf("%f",&roamingCharges);

        if (file!=NULL)
        fprintf(file, "%.0lf\t%.0f\t\t\t%.0f\t\t\t\t%.0f\n",phoneNumber,localCharges,internationalCharges,roamingCharges);

        printf("\n");
        printf("Want to Continue Writing? (Y/N)");  
        scanf(" %c",&wantToContinue);
        if(wantToContinue=='Y'){
                wantToContinue='Y';
        }else if(wantToContinue=='N'){
                wantToContinue='N';
                fclose(file);
        }
        printf("\n");
    }



return 0;
}

这是Phone Bill.txt将内容写入文件后的截图:

Phone Bill Screenshot

这是我用来从Phone Bill.txt 文件中读取内容(数字)的代码:

#include<stdio.h>
int main(){
    FILE *file;

    char strings[200];
    double phoneNumber; 
    float localCharges, internationalCharges, roamingCharges;

    file=fopen("Phone Bill.txt","r");

    if(file!=NULL){
        fscanf(file,"%.0lf\t%.0f\t\t\t%.0f\t\t\t\t%.0f\n",phoneNumber,localCharges,internationalCharges,roamingCharges);
        printf("%.0lf %0.f %0.f %0.f",phoneNumber,localCharges,internationalCharges,roamingCharges);
    }
return 0;
}

但我的输出是:

0 0 0 0

你能告诉我为什么会出现这个错误吗???*

谢谢!

【问题讨论】:

  • 您确实意识到scanf 会返回一个值
  • (除了指向目标变量外,还需要考虑文件中的第一行,其条目不是数字。)
  • 这会容易得多,因为该文件已经格式化为在终端(在 Windows 中)“type 'phone bill.txt'”(在 linux 中)“cat 'phone bill.txt”。 txt'" 但是,在文件名中间放置一个空格(几乎)总是一个坏主意。

标签: c file file-io


【解决方案1】:

首先,您尝试扫描文件的第一行 headings

其次,您需要从fscanf 格式定义中去除所有干扰:这些格式类型会自动忽略前导空格。

第三,您需要将地址传递给fscanf。这是一个有效的编辑。

#include <stdio.h>

int main(){
    FILE *file;
    char strings[200];
    double phoneNumber; 
    float localCharges, internationalCharges, roamingCharges;
    file=fopen("Phone Bill.txt","r");
    if(file!=NULL){
        fgets(strings, sizeof strings, file);       // read the headings
        fscanf(file,"%lf%f%f%f", &phoneNumber, &localCharges, &internationalCharges, &roamingCharges);
        printf("%.0lf %0.f %0.f %0.f", phoneNumber, localCharges, internationalCharges, roamingCharges);
        fclose(file);                               // don't forget to close
    }
    return 0;
}

此外,您必须检查来自fscanf 的返回值,它应该是4 扫描的项目数。

最后,我建议phoneNumber 不应该是double 甚至是unsigned long long,而应该是char phoneNumber[MAXPHLEN]。电话号码可以以000 开头,否则会丢失。更一般地说,这也将适应 IDD 中使用的 + 和数字的字母等价物,这些数字在某些电话拨号上曾经使用过,也许现在仍然使用。

EDIT 来自 OP 关于使用字符串作为电话号码的评论。我限制字符串输入长度以防止溢出,并检查扫描的项目数 - 在循环中读取所有数据。

#include <stdio.h>

#define MAXPHLEN 50

int main(){
    FILE *file;
    char strings[200];
    char phoneNumber[MAXPHLEN];
    float localCharges, internationalCharges, roamingCharges;
    file=fopen("Phone Bill.txt","r");
    if(file!=NULL){
        fgets(strings, sizeof strings, file);       // read the headings
        while((fscanf(file,"%49s%f%f%f", phoneNumber, &localCharges, &internationalCharges, &roamingCharges)) == 4) {
            printf("%s %0.f %0.f %0.f\n", phoneNumber, localCharges, internationalCharges, roamingCharges);
        }
        fclose(file);                               // don't forget to close
    }
    return 0;
}

【讨论】:

  • 你能告诉我char[MAXPHLEN]的使用方法吗?
  • 您能告诉我如何获得第二个数字及其相关数据吗?
  • 谢谢,为什么我们将 fscanf 数据等于 4?
  • 先生,这部分是什么意思? "%49s%f%f%f"
  • 我已修改编辑以读取所有文件。现在已经足够了:请阅读scanf 系列的手册页,了解函数返回值的含义(尽管我已经提到过),正如我已经提到的,您必须限制字符串输入长度。
【解决方案2】:

改变你的 fscanf 指向变量:

所以:

fscanf(file,"%.0lf\t%.0f\t\t\t%.0f\t\t\t\t%.0f\n",&phoneNumber,&localCharges,&internationalCharges,&roamingCharges)

【讨论】:

    【解决方案3】:

    一般来说,应该始终使代码尽可能简单(而不是更简单)

    以下建议代码:

    1. 编译干净
    2. 执行所需的功能

    注意:由于文件已经格式化,只需要将这些行回显到终端即可。

    #include <stdio.h>  // fgets(), fopen(), fclose(), puts(), perror()
    #include <stdlib.h> // exit(), EXIT_FAILURE
    
    int main( void )
    {
        char strings[200];
    
        FILE *fp = fopen("Phone Bill.txt","r");
        if( !fp )
        {
            perror( "fopen to read Phone Bill.txt failed" );
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        // read, print each line:
        while( fgets( strings, sizeof( strings ), fp ) )
        {
            puts( strings );
        }
    
        if( !feof( fp ) )
        { // then read error
            perror( "read of Phone Bill.txt failed" );
            fclose( fp );
            exit( EXIT_FAILURE );
        }
    
        fclose( fp );
        return 0;
    } // end function: main
    

    关于 OP 发布的代码以读取文件:

    \t 是“空白”,因此不应在 fscanf() 格式字符串中

    文件的第一行不是数据的一部分,所以需要单独读入,建议使用fgets()读入strings[]然后可以立即回显puts()

    文件末尾的第二行可以很容易地阅读:

    while( 4 == fscanf( file, " %lf %f %f %f", &phoneNumber, &localCharges, &internationalCharges, &roamingCharges ) ) 
    {
        ....
    }
    

    fscanf() 的格式字符串可以进一步减少(因为 %f 和 %lf 输入/格式规范将前导“空白”丢弃到:

    "%lf%f%f%f"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 2020-08-16
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      相关资源
      最近更新 更多