【问题标题】:fscanf to structure arrayfscanf 到结构数组
【发布时间】:2013-11-07 21:59:59
【问题描述】:

我正在尝试从文本文件中获取一些输入,将其放入结构中并打印出来。示例文本文件如下所示:

2
Curtis
660-------
Obama
2024561111

(第一个号码上的数字被划掉(为了隐私),第二个是 Whitehouse.gov 的号码,我打过电话,他们帮不了我。)

示例输出:

204-456-1111 Obama
660--------- Curtis

(当我弄清楚其余部分时,格式和排序应该不是问题。)

我的问题由下面的问号标记(在第一个 FOR 循环中,如何从文本文件中获取特定行来创建结构?

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

struct telephone {
char name[80];
long long int number;
}

main() {

struct telephone a, b;
char text[80];
int amount, i;

FILE *fp;
fp = fopen("phone.txt", "r");
fscanf(fp, "%d", amount);
struct telephone list[amount];

for(i = 0; i < amount; i++) {
    strcpy(list[i].name, ???);
    list[i].number, ???);
}
fclose(fp);

for(i = 0; i < amount; i++) {
    DisplayStruct(list[i]);
}
}

DisplayStruct(struct telephone input) {
printf("%lld %s\n", input.number, input.name);
}

【问题讨论】:

    标签: c input structure scanf


    【解决方案1】:

    使用fgets 一次读取一行。

    int lnum = 0;
    char line[100];
    while( fgets(line, sizeof(line), fp) ) {
        lnum++;
        printf( "Line %d : %s\n", lnum, line );
    }
    

    然后您可以使用sscanfstrtok 或许多其他方法从您刚刚读取的字符串中提取数据。

    我建议不要将您的电话号码存储为整数。电话号码最好用字符串表示。

    【讨论】:

    • 哎呀,我的例子中的 printf 坏了!已经修好了。
    • 哦!哈哈,是的,我想知道,这应该很有帮助,谢谢你的提示。 :)
    【解决方案2】:

    如果您可以保证姓名和电话号码中都没有空格,则可以使用fscanf() 读取此数据:

    for(i = 0; i < amount; i++) {
        fscanf("%s %lld", list[i].name, &list[i].phone);
    }
    

    注意事项:

    • 必须检查转换错误
    • 这种方法对输入错误的容忍度较低(在使用 fgets() 的情况下,可能更容易恢复和删除格式错误的条目 - 除非记录的字段数错误)。

    【讨论】:

    • 这忽略了第一行告诉有多少条目,我也找不到让 fgets 在这个程序的上下文中工作的方法。 :(
    • 是的,您可能知道有多少条目,但是在您的输入中引入一个空白(或虚假行)会完全打乱进一步的解析。
    【解决方案3】:

    同意@paddy,使用字符串存储电话号码。 (应对前导 0、变体长度、#、*、暂停等)。还不如确保它足够大以容纳int64_t
    注意:网络上有 22 位数字的示例。

    struct telephone {
      char name[80];
      char number[21];
    }
    

    要读入数据...

    for (i = 0; i < amount; i++) {
      // +1 for buffer size as string read has a \n which is not stored.
      char na[sizeof list[0].name + 1];
      char nu[sizeof list[0].number + 1];
      if ((fgets(na, sizeof na, fp) == NULL) || (fgets(nu, sizeof nu, fp) == NULL)) {
        break; // TBD, Handle unexpected missing data
      }
      // The leading space in the format will skip leading white-spaces.
      if (1 != sscanf(na, " %79[^\n]", list[i].name)) {
        break; // TBD, Handle empty string
      }
      if (1 != sscanf(na, " %20[^\n]", list[i].number)) {
        break; // TBD, Handle empty string
      }
    }
    if (fgetc(fp) != EOF) {
      ; // Handle unexpected extra data
    }
    amount = i;
    

    写作

    // Pass address of structure
    for(i = 0; i < amount; i++) {
      DisplayStruct(&list[i]);
    }
    

    void DisplayStruct(const struct telephone *input) {
      if (strlen(input->number) == 10) {
        printf("%.3s-%.3s-%4s", input->number, &input->number[3], &input->number[6]);
      }
      else { // tbd format for unexpected telephone number length
        printf("%13s", input->number);
      }
      // Suggest something around %s like \"%s\" to encapsulate names with spaces
      printf(" %s\n", input->name);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      • 2013-11-10
      • 2013-02-08
      • 2019-04-27
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多