Функция в моем коде работает неправильно

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>   
#define I 27
#define DosyaAdi "test.txt"

struct  müşteri
{
    char iban[I];
    long long tc;
    int bakiye;
};

int ibankontrol(char iban[])
{
    if (!isalpha(iban[0]) || !isalpha(iban[1]))
        return 0;
    for (int i = 2; i < 27; i++)
    {
        if (iban[i]<48 || iban[i]>57)
        {
            return 0;
        }
    }
    return 1;
}

int tckontrol(long long tc)
{
    int a=0,bas;
    long long i=1;
    while (a<11)
    {
        bas=(tc/i)%10;
        if (bas<0 || bas>9)
        {
            return 0;
        }
        
        i*=10;
        a++;
    }
    if (tc / i > 0) {
        return 0;
    }
    return 1;
}

int kaydet(struct müşteri m)
{
    FILE *dosya;
    dosya=fopen(DosyaAdi,"a");
    if (dosya==NULL)
    {
        printf("\nKayıt başarısız\n");
        return 0;
    }
    
    fprintf(dosya,"%lld %d %s\n",m.tc,m.bakiye,m.iban);

    fclose(dosya);
    return 1;
}

int havale(char kaynak[],char hedef[],int miktar)
{
    struct müşteri müşteriler[100];
    int i=0,y=0,z=0;
    char string[100];
    FILE *dosya;
    dosya=fopen(DosyaAdi,"r");
    while (1)
    {
        if ((fgets(string,100,dosya))==NULL)
        {
            break;
        }
        sscanf(string,"%lld %d %s",&müşteriler[i].tc,&müşteriler[i].bakiye,müşteriler[i].iban);
        i++;
    }   

    for(z=0;z<i;z++)
    {
        printf("\nGuncel bilgiler:\n");
        printf("%d: %s  %lld  %d\n",z+1,müşteriler[z].iban,müşteriler[z].tc,müşteriler[z].bakiye);
    }

    fclose(dosya);
    for (int j = 0; j < i; j++)
    {
        if (strcmp(kaynak,müşteriler[j].iban) == 0)
        {
            müşteriler[j].bakiye -= miktar;
            y++;
        }
        if (strcmp(hedef,müşteriler[j].iban) == 0)
        {
            müşteriler[j].bakiye += miktar;
            y++;
        }
    }

    if (y != 2)
    {
        return 0;
    }
    
    dosya = fopen(DosyaAdi, "w");
    if (dosya == NULL)
    {
        printf("Dosya açılamadı.\n");
        return 0;
    }
    
    for (int s = 0; s < i; s++)
    {
        fprintf(dosya, "%lld %d %s", müşteriler[s].tc, müşteriler[s].bakiye, müşteriler[s].iban);
        if (s!=i-1)
        {
            printf("\n");
        }
        
    }
    fclose(dosya);
    
    return 1;
}


int main()
{
    int seçim;
    int dönüş=0,kontrol=0;
    char kaynak[27],hedef[27];
    int miktar=0;
    struct müşteri m;

    while (1)
    {
        printf("Menü:\n");
        printf("1:Kayıt\n");
        printf("2:Havale\n");
        printf("3:Çıkış\n");
        printf("Seçiminiz: ");
        scanf("%d",&seçim);

        switch (seçim)
        {
        case 1:
       
            while (1)
            {
                printf("İban giriniz: ");
                scanf("%s",m.iban);
                fflush(stdin);
                dönüş=ibankontrol(m.iban);
                if (dönüş==0)
                {
                    printf("İban yanlış");
                }
                else if (dönüş==1)
                {
                    break;
                }
            }
            while (1)
            {
                printf("TC giriniz");
                scanf("%lld",&m.tc);
                dönüş=tckontrol(m.tc);
                if (dönüş==0)
                {
                    printf("TC yanlış");
                }
                else if (dönüş==1)
                {
                    break;
                }
            }
            
            printf("Bakiye giriniz");
            scanf("%d",&m.bakiye);

            kontrol=kaydet(m);
            if (kontrol==0)
            {
                printf("Kayıt başarısız");
            }
            else if (kontrol==1)
            {
                break;
            }
            break;
        case 2:
            printf("Kaynak iban: ");
            scanf("%s",kaynak);
             
            fflush(stdin);
            
            printf("Hedef iban: ");
            scanf("%s",hedef);
   
            fflush(stdin);

            printf("Gönderilicek miktar: ");
            scanf("%d",&miktar);

            int a=havale(kaynak,hedef,miktar);
            if (a==0)
            {
                printf("Havale başarısız\n");
            }
            break;
        case 3:
            exit(2);
            break;
        default:
            printf("geçersiz işlem");
            break;
        }
    }
    return 0;
}

В моем коде по мере ввода информации я обрабатываю ее в файл, а затем, при совершении передачи, удаляю файл и записываю его обратно в файл после транзакции. Хотя процесс регистрации в моем коде выполняется правильно, транзакция передачи не происходит должным образом. Я думаю, что это пробельный символ, но что вы думаете?

Каковы именно данные, которые вы предоставляете? Каков ваш ожидаемый результат? Каков фактический результат?

Retired Ninja 07.06.2024 23:09

Вам следует прочитать Использование fflush(stdin)

Retired Ninja 07.06.2024 23:11

Не используйте код типа if (iban[i]<48 || iban[i]>57). Используйте if (!isdigit(iban[i]))

Barmar 07.06.2024 23:11

Распечатайте \n для последней строки и отсканируйте ее с новой строки. Также вы не проверяете, что tc может быть отрицательным.

Joop Eggen 07.06.2024 23:25

Сообщения об ошибках относятся к stderr и должны содержать причину: if (dosya == NULL) { perror(DosyaAdi); ...}

William Pursell 07.06.2024 23:25

@JoopEggen: Вы сказали «и сканировать с новой строкой». Если под этим вы имели в виду «завершить формат scanf() новой строкой», то это крайне плохой совет. См. Каков эффект конечных пробелов в строке формата scanf()? См. также Использование fflush(stdin)? и scanf() оставляет новую строку в буфере?

Jonathan Leffler 08.06.2024 05:19

@JonathanLeffler, конечно, прав; Я хотел рассмотреть stackoverflow.com/a/5240807/984823 . Комментирование sscanf(data, "%ms", &buffer) может быть решением проблемы переполнения буфера. (строка, выделяющая scanf, конечно, злой ввод может привести к очень длинным строкам).

Joop Eggen 08.06.2024 08:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Когда вы записываете в файл, у вас нет разделителя после поля iban. Поэтому, когда вы попытаетесь прочитать файл, следующий элемент tc будет прочитан как часть iban, и вы потеряете синхронизацию.

Запишите каждый элемент в отдельную строку. Новая строка завершит чтение iban.

fprintf(dosya, "%lld %d %s\n", müşteriler[s].tc, müşteriler[s].bakiye, müşteriler[s].iban);

Есть ли способ сделать это по три, один под другим, или именно так, как вы говорите?

Morpen 07.06.2024 23:21

Вы можете использовать "%lld\n%d\n%s\n", чтобы записать каждое значение в отдельной строке. При сканировании любой пробел действует как разделитель.

Barmar 07.06.2024 23:23
Ответ принят как подходящий

Распечатайте \n для последней строки и отсканируйте ее с новой строки. Также вы не проверяете, что tc может быть отрицательным.

И IBAN не резервирует место для терминации '\0', и нет проверки при терминации, как strlen. Таким образом, printf и scanf будут ошибаться.

О, спасибо за совет по sscnf и printf. Я сделаю это снова с другими функциями.

Morpen 07.06.2024 23:32

Другие вопросы по теме