使用 put in for 循环以表格格式打印名称,但仅正确打印姓氏

Posted

技术标签:

【中文标题】使用 put in for 循环以表格格式打印名称,但仅正确打印姓氏【英文标题】:Printing names in tabular format using puts in for loop, but only last name is printed correctly 【发布时间】:2021-09-28 16:37:06 【问题描述】:

创建一个结构来指定银行客户的数据。要存储的数据是:账号、姓名、账户余额。假设银行中最多有 200 名客户。

struct CustomerData 
   int   acNum;
   float balance;
   char name[];
 n[2];

void main() 
    for(int i = 0;i<2; i++) 
        printf("give Ac. no. of %d customer\n",i+1);
        scanf("%d",&n[i].acNum);
        printf("balance of customer %d\n",i+1);
        scanf("%f",&n[i].balance);
        printf("Name of customer %d\n",i+1);
        fflush(stdin);
        gets(n[i].name);
    

    printf(" Name      Acc. no    Balance \n");

    for(int i =0;i<2;i++) 
        printf("%c      %d           %f\n",puts(n[i].name),n[i].acNum,n[i].balance);
    

输出:

give Ac. no. of 1 customer
50054
balance of customer 1
11316
Name of customer 1
sahil
give Ac. no. of 2 customer
15655
balance of customer 2
100
Name of customer 2
Rishav
 Name      Acc. no    Balance
'=
       50054           11316.000000
Rishav
       15655           100.000000

Process returned 34 (0x22)   execution time : 25.120 s
Press any key to continue.

【问题讨论】:

fflush 在输入流上调用未定义的行为,gets(n[i].name); 不仅是错误的,因为它使用的是标准库中不再存在的函数,更糟糕的是它针对的是一个灵活的数组成员,它没有“那里”在那里。无论什么书/网站教这个,烧掉它。 为什么要打印puts的结果?您似乎错过了初学者教科书前几章的一些关键部分。如果你没有书,请买一本。 你的结构中的the flexible array member name 不是动态数组。没有为它分配空间。你真的需要一本像样的初学者书,从一开始就开始阅读。不管你目前用来学习 C 的任何资源,都扔掉。 Sahil Dadhwal,允许的最长名字是多少? 600+ letters? Sahil Dadhwal,我建议放弃scanf()。使用fgets()将用户输入的每一行读入一个字符串,然后解析该字符串。 【参考方案1】:

正如 cmets 中提到的,您的代码中有几个问题:

    永远不要fflush(stdin)。它会导致未定义的行为。 切勿使用scanf() 读取输入。请改用fgets()。 您应该正确缩进您的代码,使其更易于阅读。

这是您的代码的更好版本:

#include <stdio.h>
#include <string.h> // for strcspn()

struct CustomerData 
    int acNum;
    float balance;
    char name[255]; // Give it a size
;

我们需要定义一个从输入中读取一行的函数(记住不要使用scanf()):

char *readstr(char *str, int size)

    if (!fgets(str, size, stdin)) 
        fprintf(stderr, "Input error\n");
        return NULL;
    
    
    str[strcspn(str, "\n")] = '\0'; // fgets() reads the ending '\n' so null-terminate the string
    return str;

您可以对ints 和floats 执行相同的操作:

int readint(int *i)

    char buffer[255];
    if (!fgets(buffer, 255, stdin)) 
        fprintf(stderr, "Input error\n");
        return 0; // failed
    

    buffer[strcspn(buffer, "\n")] = '\0';
    
    if (sscanf(buffer, "%d", i) != 1)
        return 0; // failed
    
    return 1; // success


int readfloat(float *f)

    char buffer[255];
    if (!fgets(buffer, 255, stdin)) 
        fprintf(stderr, "Input error\n");
        return 0; // failed
    

    buffer[strcspn(buffer, "\n")] = '\0';
        
    if (sscanf(buffer, "%f", f) != 1)
        return 0; // failed
        
    return 1; // success

现在,您可以在 main() 中使用这些功能:

int main() // main() should always return an int

    const int num_customers = 2; // In case you wanted to change it later
    struct CustomerData n[num_customers];
    
    for(int i = 0; i < num_customers; i++) 
        printf("give Ac. no. of %d customer: ", i+1);
        readint(&n[i].acNum);
        
        printf("balance of customer %d: ", i+1);
        readfloat(&n[i].balance);
        
        printf("Name of customer %d: ", i+1);
        readstr(n[i].name, sizeof(n[i].name));
    
    
    printf("\nName\tAcc. no\tBalance\n");
    
    for(int i = 0; i < num_customers; i++)
        printf("%s\t%d\t%f\n", n[i].name, n[i].acNum, n[i].balance);

示例输出:

give Ac. no. of 1 customer: 1
balance of customer 1: 12
Name of customer 1: john
give Ac. no. of 2 customer: 2
balance of customer 2: 65.5
Name of customer 2: wick

Name    Acc. no Balance
john    1       12.000000
wick    2       65.500000

【讨论】:

以上是关于使用 put in for 循环以表格格式打印名称,但仅正确打印姓氏的主要内容,如果未能解决你的问题,请参考以下文章

为啥 for-in 循环不打印我想要的内容? [复制]

在 for 循环中使用切换

shell脚本--------for循环

Shell语法—— for 循环

C程序如何以表格格式对齐打印

Python 3初学者,如何实现for循环打印一个字符串,比如“abcdef”,按照如下格式