CodeMine Ответов: 3

Изменение записи в C не работает


Я написал эту программу на языке C. часть приема и отображения данных работает нормально. Но когда я пытаюсь найти запись и изменить ее с новыми данными, это не работает.

#include <stdio.h>
#include <string.h>
int main()
{
    int tf=0;
    int i=0;
    int j=0;
    char temp[20];
    FILE *fw,*fr;
    char opsn='y';
    char *p;
    int count=0;
    //for writing records into file
    struct student
    {
        char name[20];
        int age;
    }s,s2;
    int recsize=sizeof(s);
    int taka;
    char stnm[20];
    char me[20];
    int ge;
    printf(" \n 1 add ");
    printf(" \n 2 show ");
    printf(" \n 3 modify");
    scanf("%d",&taka);
    if(taka==1)
    {
        fw=fopen("op.txt","a");
        while(opsn=='y')
        {
            count++;
            printf("Enter student name and age\n");
            scanf("%s%d",&s.name,&s.age);
            fprintf(fw,"%s\t%d\n",s.name,s.age);
            printf("Want another record(y|n)\n");
            fflush(stdin);
            opsn=getche();
        }
        fclose(fw);
    }
    if(taka==2)
    {
        //for reading records rom file
        fr=fopen("op.txt","r");
        printf("\nRecord from file is\n");
        i=0;
        while(fscanf(fr,"%s\t%d\n",s.name,&s.age)!=EOF)
        {
            printf("%s %d\n",s.name,s.age);
        }
    }
    //for modifying records rom file
    if(taka==3)
    {
        fr=fopen("op.txt","r+");
        printf("\nEnter name of student to modify");
        scanf("%s",&stnm);
        printf("ok");
        rewind(fr);
        while(fscanf(fr,"%s\t%d\n",&s.name,&s.age)!=EOF)
        {
            if(strcmp(s.name,stnm)==0)
            {
                printf("\nenter new name,age");
                scanf("%s%d",&me,&ge);
                strcpy(s.name,me);
                s.age=ge;
                fseek(fr,recsize,SEEK_SET);
                fprintf(fr,"%s\t%d\n",s.name,s.age);
                break;
            }
            recsize = recsize * tf;
            printf("%s %d  %d\n",s.name,s.age,tf);
            tf++;
        }
        printf(" Done ");
    }
}


Что я уже пробовал:

пробовал с fread() и fwrite()
это работает.

Но я хочу сделать то же самое с помощью программы обновления файлов
fprintf()
fscanf()

3 Ответов

Рейтинг:
9

CodeMine

Один из моих друзей помог мне.

Решение-
если(така==3)
{
fr=fopen("op.txt","Р");
ft=fopen("opt.txt","w");

printf("\nEnter имя студента для изменения");
scanf("%s",&stnm);

перемотка назад(фр);
пока(функции fscanf(фр,"%з\т%д\п",&амп;ы.имя,&амп;ы.возраст)!=ВФ)
{

if(strcmp(s.name,stnm)==0)
{
printf("\nenter новое имя,возраст");
то scanf("%С%Д", и усилитель;я,&ампер;Гэ);
strcpy(s.name,я);
С. возраст=Гэ;
fprintf(футы,"%з\т%д\п",с. название,С. возраст);
}
еще
{
fprintf(футы,"%з\т%д\п",с. название,С. возраст);
}


}

fclose(фр);
fclose(ft);
fr=fopen("op.txt","w");
ft=fopen("opt.txt","Р");
пока(функции fscanf(футы,"%з\т%д\п",&амп;ы.имя,&амп;ы.возраст)!=ВФ)
{
fprintf(фр,"%з\т%д\п",с. название,С. возраст);
}
}


Рейтинг:
28

KarstenK

Улучшить ваш код и проверять коды возврата, как из fprintf.

Вы пропустили звонок fclose в конце.

PS: ваш код выглядит как "нацарапанный из кода обезьяны" ;-)


Рейтинг:
0

OriginalGriff

Я не пробираюсь через это: он неиндентирован или плохо отступлен, недокументирован, раскомментирован, использует "ленивые" имена переменных и монолитен.

Начните с правильного отступа, чтобы было легче читать: выберите стиль отступа и будьте последовательны. Не имеет значения, что вы выбрали: K&R. Уайтсмиты, даже отвратительный 1ТБ подойдет - просто будьте последовательны.
Затем переименуйте переменные, чтобы они отражали то, для чего они используются: s2, me, ge, i, j ... просто их легко печатать, они не помогают вам понять код, и поэтому они могут легко вызвать проблемы, используя неправильную переменную. index, userInput, и так далее может быть больше времени для ввода, но они помогают коду стать самодокументируемым и более надежным.
Затем разбейте его на функции: вместо встроенного кода в одной функции напишите InsertRow функция, и вызовите ее из вашего main, то же самое с DisplayRow и DisplayAllRows. Затем создайте UpdateRow функция и вызов этого также.

Тогда вы можете начать исправлять все, что с ним не так: мы понятия не имеем, и "это не работает" не говорит нам абсолютно ничего. Мы понятия не имеем, какие данные у вас были раньше, что вы с ними сделали и что вы получили! Так что все будет зависеть от тебя.
К счастью, у вас есть инструмент, который поможет вам выяснить, что происходит: отладчик. Как вы его используете, зависит от вашей компиляторной системы, но быстрый поиск в Google имени вашей IDE и "отладчика" должен дать вам необходимую информацию.

Поместите точку останова в первую строку функции и запустите код через отладчик. Затем посмотрите на свой код и на свои данные и определите, что должно произойти вручную. Затем по одному шагу в каждой строке проверяйте, что то, что вы ожидали, произойдет именно так, как и произошло. Когда это не так, тогда у вас есть проблема, и вы можете вернуться назад (или запустить ее снова и посмотреть более внимательно), чтобы выяснить, почему.

Извините, но мы не можем сделать это за вас - пришло время вам освоить новый (и очень, очень полезный) навык: отладку!


Stefan_Lang

"К&амп;Р. Whitesmiths, даже отвратительная 1ТБ "
Мне пришлось посмотреть его, потому что я нигде не слышал о "1TB", но согласно Википедии K&R и 1TBS - это одно и то же (предполагая, что вы имеете в виду 1TBS-все ссылки на " 1TB " приводят к страницам, говорящим о памяти). Я знаю их под названием "египетский стиль" или "египетские скобки", которые я считаю гораздо более самодокументирующим названием ;-)

OriginalGriff

1TB всегда использует скобку, даже когда в этом нет необходимости, K&R этого не делает.

То, что я хотел сказать, было "Allman", а не K&R, но было раннее утро, и мой мозг не работал полностью ...

Stefan_Lang

Я вижу. Википедия не делает такого различия для стилей в целом, только как вариант. видишь ли https://en.wikipedia.org/wiki/Indentation_style

Согласно этой странице, Allman отличается от K&R тем, что он помещает открывающую скобку на новую строку.

Лично я использую стиль Страуструпа, главным образом потому, что книга Страуструпа-это книга на C++, на которую я ссылался большую часть времени. Теперь я полагаюсь на Clang-Tidy, чтобы сделать форматирование для меня, и он настроен на использование стиля Allman.