【问题标题】:C Program not printing the string in a structureC程序不在结构中打印字符串
【发布时间】:2021-03-30 07:52:50
【问题描述】:

我编写了一个程序,将多个输入作为字符串进行存储和打印。 不知何故,存储在a[i].acn 中的“帐号”没有打印出来。我试过调试,问题似乎出在向 a[i].name 添加空格的循环中。

#include <stdio.h>
#include <string.h>
struct Bank
{
    char name[10],acn[8];
    float bal;
}a[100];
int n,i,flag;
void add()
{
//function to add Rs. 100 to accounts that have balance over 1000
//and print the details.
    for(i=0;i<n;i++)
        if(a[i].bal>=1000)
            a[i].bal+=100;
    printf("\nS.No.\tName\t\tAcc. No.\tBalance(in Rs.)");
    for(i=0;i<n;i++)
        printf("\n[%d]\t%s\t%s\t%.2f",i+1,a[i].name,a[i].acn,a[i].bal);
}
void main()
{
    printf("Enter the number of customers: ");
    scanf("%d",&n);
    printf("Enter the details of %d customers:\n",n);
    for(i=0;i<n;i++)
    {
        printf("\nCustomer-%d",i+1);
        printf("\nFirst Name: ");
        fflush(stdin);
        gets(a[i].name);
        printf("Account Number: ");
        fflush(stdin);
        gets(a[i].acn);
        printf("Account Balance: ");
        scanf("%f",&a[i].bal);
    }
    for(i=0;i<n;i++)//The problem seems to be in this loop
        while(strlen(a[i].name)<10)
            strcat(a[i].name," ");
    add();
}

输入:

Enter the number of customers: 2
Enter the details of 2 customers:

Customer-1
First Name: Aarav
Account Number: ASDF1234
Account Balance: 1200

Customer-2
First Name: Asd
Account Number: abcd1122
Account Balance: 999.9

输出:

S.No.   Name            Acc. No.        Balance(in Rs.)
[1]     Aarav                   1300.00
[2]     Asd                     999.90

【问题讨论】:

  • 使用了什么输入?
  • @chux-ReinstateMonica ,我的错。我也会编辑并添加输入。
  • fflush(stdin); 刷新输入流会导致未定义的行为

标签: c string for-loop structure


【解决方案1】:

scanf() 然后gets() 不好

scanf("%d",&amp;n); 读取整数,但在stdin 中留下以下'\n'gets() 读取为空字符串 ""

我建议使用fgets() 将所有行读入一个相当大的缓冲区,然后使用sscanf()strtol() 等进行解析。


代码溢出缓冲区

a[i].nam 只能容纳 9 个字符,然后是 空字符。追加一个空格,直到它的长度超过 9 个溢出 .name[10]

struct Bank {
  char name[10],acn[8];
  float bal;
} a[100];

while(strlen(a[i].name)<10)
   strcat(a[i].name," ");

使用while(strlen(a[i].name)&lt;9) 填充空格,但不要太多。


金钱需要特别的considerations。现在,考虑最低面额(美分)的long。阅读double,然后阅读long balance = lround(input*100.0);

存在其他弱点。

【讨论】:

  • 是的,gets after scanf 不好,但是....gets 总是不好 - 即使没有 @987654342 @就在之前。
  • 感谢@chux-ReinstateMonica 的回答!
【解决方案2】:

您的程序中需要纠正的地方很少。

  1. 使用fgets 而不是gets,因为在gets 中没有边界检查,并且存在读取超出分配大小的危险。

  2. 当使用fgetsscanf甚至gets时,它们都会从标准缓冲区中读取剩余的\n字符,所以使用fgets如果我们正确使用它,我们可以避免它。(@987654330 @ 也避免了空格字符,但它不能用于读取多字字符串)

  3. 删除fflush(stdin),不需要你可以看到原因here

  4. 最后,但同样重要的是使用int main() 而不是void main()

【讨论】:

  • 第 2 点在几个方面不正确,例如scanf 无法读取多字字符串 - 它可以。
  • @4386427,请提及这些,将添加到答案中,最终目标是提供帮助。
  • "scanf ... but it cannot be used to read multiword strings" --> scanf("%*[^\n]%*1[\n]" "%*[^\n]%*1[\n]" "%*[^\n]%*1[\n]" ); 可以很好地读取 3 行非空输入。不过,使用fgets() 是一个且更可取的主意。
  • @chux-ReinstateMonica,这很高兴知道,然后我应该将我的答案更改为 它无法直接读取(仅使用 %s),除非我们使用少数列表转义序列字符。
  • 感谢大家的回答和帮助 cmets!
【解决方案3】:

你有这个:

struct Bank
{
    char name[10],acn[8];
    float bal;
}a[100];

由于 C 字符串必须以 NUL 字符(又名 '\0')结尾,name 的长度最多为 9 个字符。

这里

    while(strlen(a[i].name)<10)
        strcat(a[i].name," ");

您不断添加空格,直到达到 10 个字符为止。换句话说 - 你在数组之外写。

name 更改为name[11]

除此之外,getsfflush(stdin) 应避免使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-23
    • 2021-05-02
    • 1970-01-01
    • 2019-09-11
    • 2013-11-04
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多