Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача с таблицами, Некорректно работает функция 
:(
    Опции темы
gfz
Дата 15.12.2005, 19:33 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Задача: Дан файл, содержащий сведения о владельцах автомобилей. Структура записи файла:
Фамилия и инициалы владельца, марка авто и номер авто. Написать прогу, которая печатает
- фамилии владельцев и комера автомобилей данной марки (в алфавитном порядке)
- количество автомобилей каждой марки

Итак, первое задание я сделал. Вот текст программы:

Код
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define DL_FIO 22
#define DL_MAUTO 10
#define DL_NOM 7
#define STRMAX 200
struct AUTO
 { char fio [DL_FIO];
   char mauto [DL_MAUTO];
   char gosnom [DL_NOM+2];
 };
struct EL_MAS
 { char fio [DL_FIO];
   char gosnom [DL_NOM+2];
 };
void AutoFIO (struct EL_MAS ms [], int *n);
void sort (struct EL_MAS ms [], int n);
int main ()
{struct EL_MAS ms [STRMAX];
 int n;
 int i;
 AutoFIO (ms,&n);
 if (n==0)
 {puts ("net avto dannoj marki");
  getch ();
  return 1;
 }
 else {sort (ms, n);
       puts ("\n Spisok vladelcev:");
       for (i=0; i<n; i++)
       {printf ("\n %d. %s %s", i+1, ms[i].fio, ms[i].gosnom);
       }

 }
getch ();
return 0;
}
void AutoFIO (struct EL_MAS ms [], int *n)
{FILE *f;int k;
 char b[DL_MAUTO];
 struct AUTO tz;
 f=fopen ("auto.txt", "r");
 if (f==NULL)
{puts ("fail auto.txt ne najden");
 getch ();
exit (2);
}
else
{puts ("vvedite marku avto");
 scanf("%s",b);
 *n=0;
 while (*n<STRMAX && fgets((char *)&tz, sizeof (tz), f)!=NULL)
  {tz.mauto [DL_MAUTO-1]='\0';
   tz.fio [DL_FIO-1]='\0';for(k=0;(tz.mauto[k]!='\0') && k<DL_MAUTO-1;k++)
    if(tz.mauto[k]==' ')
      tz.mauto[k]='\0';
     if (strcmp(tz.mauto,b)==0)
  {
   strcpy (ms[*n].gosnom, tz.gosnom);
   strcpy (ms[*n].fio, tz.fio);
   (*n)++;
}}
}
}

void sort (struct EL_MAS ms [], int n)
{
int k, i=0;
struct EL_MAS s;
for (k=n=1; k>=1; k--)
if (strcmp (ms[i].fio, ms[i+1].fio)>0)
{s=ms[i];
 ms[i]=ms[i+1];
 ms[i+1]=s;
}
}


А вот второе задание, как ни пытался, не выходит. Я знаю, что там надо работать с таблицами, но что-то не получается. Вот текст той программы, что я сделал:

Код

# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
#include<string.h>
# define DL_FIO 22
# define DL_MAUTO 9
# define DL_NOM 6
struct AUTO
{char fio [DL_FIO];
 char mauto [DL_MAUTO];
 char nom [DL_NOM+2];
};
int main (void)
{int n=0;
 int tab [31]={0};
 char mmauto [31][9]={' '};
 FILE *f;
struct AUTO tz;
int i;
f=fopen ("auto.txt", "r");
if (f==NULL)
{
puts ("fail auto.txt ne najden");
getch ();
return 1;
}
while (fgets ((char *)&tz, sizeof (struct AUTO), f))
{tz.mauto[DL_MAUTO-1]='\0';
for (i=0; i<31; i++)

if (strcmp(mmauto[i],tz.mauto)==0)
       {tab[i]++;
    n=1;
    break;
       }
else if(mmauto[i][0]==' ')
      {strcpy(mmauto[i],tz.mauto);
       tab[i]=1;break;
       }
}
if (n==1)
{printf ("avto kolichestvo\n");
puts ("==================================");
for (n=0; n<i; n++)
printf ("%s  %d",mmauto[n],tab[n]);
}
getch ();
fclose(f);
return 0;
}


Результат был примерно такой:
Mazda 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
А должен быть таким:
Mazda 6
BMW 5
VW 4
и т.д.
(цифра - количество машин данной марки, встречающихся в файле, в примере цифры взяты наугад)

Помогите решить. Скачать файл (auto.txt), в котором занесены фамилии владельцев, марки автомобилей и гос. номера можно тут http://webfile.ru/692750
  Вверх
blackofe
Дата 15.12.2005, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 29.11.2005

Репутация: 4
Всего: 4



значит так.

1. поле названий автомобилей в твоем файле имеет длину не 9, а 10.

2. вот таким выражением int tab[31] = { 0 }; ты не инициализируешь массив - только первый элемент. а ведь ты потом обращаешься к элементам массива с надеждой, что там лежат нули или пробелы. надо использовать memset для инициализации обоих массивов.

3. понятно, что ты пытаешься n использовать как индикатор - есть у нас автомобили или нет. но проще просто смотреть по массиву - если tab[i] равен нулю, значит данных уже нет. кстати, использование выражения n < i совершенно непонятно, потому что i у нас может быть вообще говоря любым - от нуля до 30.

4. в формат printf надо добавить "\n", чтобы у тебя печаталось по строкам.

примерный вид после изменений и (слегка) подрехтованного кода (я его покрутил под себя - мне так было проще разбираться) получается следующий:

Код

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

#define DL_FIO        22
#define DL_MAUTO    10
#define DL_NOM        6

struct AUTO {
    char fio[DL_FIO];
    char mauto[DL_MAUTO];
    char nom[DL_NOM+2];
};

int main()
{
    int tab[31];
    memset(tab, 0, sizeof(tab));
    char mmauto[31][DL_MAUTO];
    memset(mmauto, ' ', sizeof(mmauto));
    AUTO tz;
    FILE *f;

    if(!(f = fopen("D:\\test\\auto.txt", "r"))) {
        printf("fail auto.txt ne najden\n");
        return 1;
    }

    while(fgets((char *)&tz, sizeof(AUTO), f)) {
        tz.mauto[DL_MAUTO-1]='\0';
        for(int i = 0; i < 31; ++i)
            if(strcmp(mmauto[i], tz.mauto) == 0) {
                tab[i]++;
                break;
            } else if(mmauto[i][0] == ' ') {
                strcpy(mmauto[i], tz.mauto);
                tab[i] = 1;
                break;
            }
    }
    printf("avto kolichestvo\n==================================\n");
    for(int i = 0; i < 31; ++i) {
        if(tab[i] == 0)
            break;
        printf("%s  %d\n", mmauto[i], tab[i]);
    }
    fclose(f);

    return 0;
}


результат работы программы:

Код

avto kolichestvo
==================================
Mazda      5
Porsche    4
BMW        5
Opel       5
VW         3
Press any key to continue


хотя, конечно же, я бы все сделал не так smile.
PM MAIL   Вверх
gfz
Дата 15.12.2005, 23:29 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спаибо огромное 8))) загнал в компилятор, выдал 13 ошибок. Загнал в другой компилятор, все работает исправно 8) только вот для удобства перед fclose (f) надо написать getch(); а то компилятор показывает результат на долю секунды 8)

Да, и еще... можешь объяснить действие оператора memset?
  Вверх
Fixin
Дата 15.12.2005, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 2
Всего: 18



Цитата(gfz @ 16.12.2005, 00:29)
можешь объяснить действие оператора memset?
Заполняет память значением на количество байт:
Код
int mass[kol_vo];
memset(mass, znachen, kol_vo*sizeof(int));
Здесь массиву задается значение znachen количеством kol_vo*sizeof(int) байт относительно адреса mass в памяти.

PM MAIL ICQ   Вверх
gfz
Дата 15.12.2005, 23:44 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











memset(tab, 0, sizeof(tab));
то есть в моем случае массиву tab в количестве sizeof(tab) (в данном случае 31) каждому элементу задается нулевое значение?
  Вверх
blackofe
Дата 16.12.2005, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 29.11.2005

Репутация: 4
Всего: 4



Цитата(gfz @ 15.12.2005, 23:29)
только вот для удобства перед fclose (f) надо написать getch(); а то компилятор показывает результат на долю секунды 8)

я работаю с vc++ 2003. при выполнении программы, запущенной из-под IDE, по окончании выдается строка "Press any key to continue", и консоль ждет нажатия любой клавиши. поэтому я getch() никогда не использую. если хочется посмотреть какие-то промежуточные результаты - на это есть дебагер с пошаговым выполнением программы.

более того, если ты пишешь консольную программу, то подразумевается, что ты ее будешь использовать в досовской консоли, которая никуда не исчезает по окончании программы.

другими словами, функция getch() используется некоторыми программистами для удобства отладки программы. для использования же она не нужна.

Это сообщение отредактировал(а) blackofe - 16.12.2005, 21:16
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1123 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.