Я сделал программу, которая принимает несколько входных данных в виде строки, сохраняет и распечатывает их.
Почему-то «Номер счета», который хранится в 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); Очистка входного потока вызывает неопределенное поведение





В вашей программе есть несколько вещей, которые нужно исправить.
Используйте fgets вместо gets, потому что в gets нет проверки границ и есть опасность чтения за пределами выделенного размера.
При использовании fgets , scanf и даже gets все они считывают оставшиеся \n символы из стандартного буфера, поэтому с помощью fgets мы можем избежать этого, если будем использовать его правильно. (scanf также избегает пробелов, но его нельзя использовать для чтения строк, состоящих из нескольких слов)
удалить fflush(stdin), это не обязательно, вы можете увидеть причину здесь
И последнее, но не менее важное: используйте int main() вместо void main().
Пункт 2 неверен по нескольким причинам, например. что scanf не может читать строки из нескольких слов — может.
@ 4386427, пожалуйста, укажите их, добавите к ответу, конечная цель - помочь.
«scanf ... но его нельзя использовать для чтения строк, состоящих из нескольких слов» --> scanf("%*[^\n]%*1[\n]" "%*[^\n]%*1[\n]" "%*[^\n]%*1[\n]" ); будет хорошо читаться в 3 непустых строках ввода. Тем не менее, использование fgets() — хорошая и предпочтительная идея.
@chux-ReinstateMonica, это полезно знать, тогда я должен изменить свой ответ на то, что он не может читаться прямо (просто используя %s), если только мы не используем несколько списков символов escape-последовательности.
Спасибо всем за ответы и полезные комментарии!
У вас есть это:
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]
Кроме того, следует избегать gets и fflush(stdin).
scanf() значит gets() плохо
scanf("%d",&n); читает целое число, но оставляет следующее '\n' в stdin, которое 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)<9), чтобы добавить пробелы, но не слишком много.
Деньги требуют особых соображений. А пока рассмотрим long наименьшего номинала (центов). Читайте в double, а затем long balance = lround(input*100.0);
Существуют и другие слабости.
Да, gets после scanf это плохо, но.... gets всегда плохо - даже без scanf непосредственно перед.
Спасибо @chux-ReinstateMonica за ответ!
Какой ввод использовался?