Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
#1

Нужна помощь в исправлении кода одной функции... - C++

12.04.2009, 20:49. Просмотров 848. Ответов 17
Метки нет (Все метки)

Плиз.. помогите исправить код функции 'void Opt()', мне необходимо было создать программу которая читатет файл 'd:\file.txt' , создает и копирует всё его содержимое в типизированный файл 'd:\out.dat'
Данная функция по теории должна работать так, вводишь число равное 500 если оптовая цена какого-либо товара равна 500 то нужно вывести на экран всю строку с этим товаром (название, оптовую и розничную цены)
Программа содержит меню:
1 Запись в файл
2 Вывод на экран
3 Очистка файла //очистка файла 'out.dat'
4 Поиск...
5 Выход

Меню Поиск ...
как раз и содержит данную функцию 'void Opt()'

Код
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

struct mon {
  char type[20];
  int opt, rozn;
  char comm[40];
};
int kol=0;
void WriteFile()
{
	FILE *fi,*fo;
	 clrscr();
	 if ((fi=fopen("D:\\file.txt", "r"))==0){
	  cout << "Error open input file!!!" ;
	  return;}
	 if ((fo=fopen("D:\\out.dat","w+b"))==0){
	  cout << "Error open output file!!!";
	  return;}
	 const int dl=80;
	 char s[dl];
	mon a;
	while(fgets(s,dl,fi)){
	strncpy(a.type,s,19);
	a.type[19]='\0';
	a.opt=atoi(&s[20]);
	a.rozn=atoi(&s[25]);
	strncpy(a.comm,&s[30],40);
	fwrite(&a,sizeof(mon),1,fo);
	kol++;
	};
	fclose(fi);
	fclose(fo);

	return;
}

void out()
{
	FILE *fo;
	clrscr();
	if ((fo=fopen("D:\\out.dat","rb"))==0){
	  cout << "Error open output file!!!";
	  return ;}
	int i;
	cout<<"Input number of Zapisi ";
	cin >>i;//после ввода i не забываем нажать Enter
	if (i>kol) {
	  cout << "Zapisi net!!!";
	  return;}

	mon a;
	fseek(fo,sizeof(mon)*(i-1),SEEK_SET);
	fread(&a,sizeof(mon),1,fo);
	cout << "Tip: " << a.type << " opt.: " << a.opt << " rozn: " << a.rozn << endl;
	fclose(fo);
}

void ClearFile()
{
	FILE *fo;
	clrscr();
	if ((fo=fopen("D:\\out.dat","wb"))==0){
	cout << "Error open output file!!!"<<endl;
	  return ;}
	fclose(fo);
}

[COLOR="Red"]void Opt()
{
  mon a;
  FILE *fo;

  if ((fo=fopen("D:\\out.dat","r"))==0){
	cout << "Error open output file!!!";
	return;}
  fseek(fo,0,SEEK_SET);
   int res;
   int p;
   do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
  fclose(fo);
   return;
}[/COLOR]
void Search()
{
 char menu_2;
 clrscr();
 int p;
 do
 {
   cout <<endl<< "1 Nazvanie" << endl <<"2 Optovaya" << endl << "3 Roznica" << endl << "4 Vozvrat v gl. menu"<< endl;
   menu_2=getch();
   switch(menu_2)
   {
	// case '1':
	  // Nazv();
	 //  break;
	 case '2':
	   cout << "Vvedite optovuy cenu: " << endl;
	   cin >> p;
	   Opt();
	   break;
	// case '3':
	  // Rozn();
	 //  break;
	  };
   if (menu_2=='4') break;
 }
 while(1);
clrscr();
}

void main()
{
 char menu;
 int i;
 kol=0;
 clrscr();
 do
 {
   cout <<endl<< "1 Zapis' v file" << endl <<"2 Vivod na ekran" << endl << "3 Ochistka file" << endl << "4  Search..."<< endl << "5 Vichod" << endl;
   menu=getch();
   switch(menu)
   {
	 case '1':
	   WriteFile();
	   break;
	 case '2':
	   out();
	   break;
	 case '3':
	   ClearFile();
	   break;
	 case '4':
	   Search();
	   break;
		 };
   if (menu=='5') break;
 }
 while(1);
}
текстовый файл выглядит так
Код
Huindai             350  400  plohoi                                  l
Samsung             500  550  norma                                   l
Sony                300  400  rtye                                    l
Acer                200  350  hgfak                                   l
помогите пожалуйста исправить эту функцию, чтото не понимаю почему она не работает... в программе она выделена красным цветом
символ 'l' в конце строки каждого файла ни имеет значения он просто показывает где заканчивается каждая строка.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2009, 20:49     Нужна помощь в исправлении кода одной функции...
Посмотрите здесь:

Нужна помощь!Ошибка в структуре. C++
Нужна помощь с классом C++
Ряд Тейлора. Нужна помощь C++
C++ прямоугольная матрица. нужна помощь
Нужна помощь Строки. C++
C++ Нужна помощь в исправлении
Нужна помощь с циклами C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Gravity
558 / 552 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
12.04.2009, 20:58     Нужна помощь в исправлении кода одной функции... #2
Код
   int res;
   int p;
   do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
Переменная p не определена, поэтому неизвестно с чем сравнивается a.opt.
Humanitis
172 / 164 / 6
Регистрация: 12.01.2009
Сообщений: 430
12.04.2009, 21:00     Нужна помощь в исправлении кода одной функции... #3
Цитата Сообщение от kandrey58region Посмотреть сообщение
int p;
do {
res=fread(&a,sizeof(mon),1,fo);
if (a.opt==p)
{ cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
}
}
а p то где-то надо инициализировать
Evg
Эксперт CАвтор FAQ
17385 / 5623 / 350
Регистрация: 30.03.2009
Сообщений: 15,402
Записей в блоге: 26
12.04.2009, 21:04     Нужна помощь в исправлении кода одной функции... #4
Переменная res так же не определена, а потому цикл наверняка окажется бесконечный, а файл при этом ограниченного размера, после чего начинается работа с залипшими данными от предыдущих итераций цикла

Добавлено через 1 минуту 20 секунд
Пардон, про res не заметил. Снимаю свою претензию
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
12.04.2009, 21:33  [ТС]     Нужна помощь в исправлении кода одной функции... #5
просто у меня p раньше иницилизировалась в меню_2
но даже если иницилизировать её в функции 'void Opt()' то никакого результата не получается
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
   int res;
   int p;
   cout << "Vvedite optovuy cenu: " << endl;
   cin >> p;
   do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
помогите пожалуйста довести эту функцию до ума
Evg
Эксперт CАвтор FAQ
17385 / 5623 / 350
Регистрация: 30.03.2009
Сообщений: 15,402
Записей в блоге: 26
12.04.2009, 21:45     Нужна помощь в исправлении кода одной функции... #6
Закомментируй строку 'if (a.opt==p)' и смотри, что печатает. Увидишь, что у тебя из файла реально программа читает и глазами хотябы оцени правильно это или нет
Gravity
558 / 552 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
12.04.2009, 22:08     Нужна помощь в исправлении кода одной функции... #7
Подозреваю, что проблема как раз во fread. Как вариант,
C
1
2
3
4
5
6
char line[80];
while(fgets(line, sizeof(line), fo) != NULL) {
   sscanf(line, "%s %d %d %s", a.type, &a.opt, &a.rozn, a.comm);
   if(a.opt == p)
      printf("%s", line);
}
Evg
Эксперт CАвтор FAQ
17385 / 5623 / 350
Регистрация: 30.03.2009
Сообщений: 15,402
Записей в блоге: 26
12.04.2009, 22:38     Нужна помощь в исправлении кода одной функции... #8
Цитата Сообщение от Gravity Посмотреть сообщение
Подозреваю, что проблема как раз во fread. Как вариант,
C
1
2
3
4
5
6
char line[80];
while(fgets(line, sizeof(line), fo) != NULL) {
   sscanf(line, "%s %d %d %s", a.type, &a.opt, &a.rozn, a.comm);
   if(a.opt == p)
      printf("%s", line);
}
Я исходники особо не смотрел, но этот файл он формирует в процедуре WriteFile через fwrite. Т.е. с этой точки зрения вроде бы как всё правильно (чтение и запись симметричны)
accept
4819 / 3239 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.04.2009, 23:18     Нужна помощь в исправлении кода одной функции... #9
внутри функции int p; убрать, перенести в void Opt()
Код
void Opt(int p)
функцию вызывать через Opt(p)
Код
       case '2':
	   cout << "Vvedite optovuy cenu: " << endl;
	   cin >> p;
	   Opt();
	   break;
Код
    do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
это можно заменить

C++
1
2
3
4
5
6
7
8
9
10
11
    while ((res = fread(&a, sizeof(mon), 1, fo)) == 1);
        if (a.opt == p)
            cout << a.type
                 << " "
                 << a.opt
                 << " "
                 << a.rozn
                 << " "
                 << a.comm
                 << " "
                 << endl;
Добавлено через 4 минуты 42 секунды
fo - file out
обычно пишут когда выводишь, а когда вводишь пишут
fi - file in
когда открываешь файл на чтение, указатель на него помещай в fi, а когда открываешь файл на запись - в fo
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
12.04.2009, 23:23  [ТС]     Нужна помощь в исправлении кода одной функции... #10
всем спасибо огромное за помощь и объяснение...
теперь появились новые проблема, почему то при использовании данной функции у меня из такого текстового файла
Код
Huindai             350  400  plohoi                                  l
Samsung             500  550  norma                                   l
Sony                300  400  rtye                                    l
Acer                200  350  hgfak                                   l
1) в конце каждой записи стоит смайлик (улыбающаяся рожица)...
2) последняя запись с монитором Acer выводится два раза, остальные записи выводятся по одному разу как положено...
как думаете с чем могут быть связаны данные проблемы

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
 
struct mon {
  char type[20];
  int opt, rozn;
  char comm[40];
};
int kol=0;
int p=0;
int v=0;
void WriteFile()
{
    FILE *fi,*fo;
     clrscr();
     if ((fi=fopen("D:\\file.txt", "r"))==0){
      cout << "Error open input file!!!" ;
      return;}
     if ((fo=fopen("D:\\out.dat","w+b"))==0){
      cout << "Error open output file!!!";
      return;}
     const int dl=80;
     char s[dl];
    mon a;
    while(fgets(s,dl,fi)){
    strncpy(a.type,s,19);
    a.type[19]='\0';
    a.opt=atoi(&s[20]);
    a.rozn=atoi(&s[25]);
    strncpy(a.comm,&s[30],40);
    fwrite(&a,sizeof(mon),1,fo);
    kol++;
    };
    fclose(fi);
    fclose(fo);
 
    return;
}
 
void out()
{
    FILE *fo;
    clrscr();
    if ((fo=fopen("D:\\out.dat","rb"))==0){
      cout << "Error open output file!!!";
      return ;}
    int i;
    cout<<"Input number of Zapisi ";
    cin >>i;//после ввода i не забываем нажать Enter
    if (i>kol) {
      cout << "Zapisi net!!!";
      return;}
 
    mon a;
    fseek(fo,sizeof(mon)*(i-1),SEEK_SET);
    fread(&a,sizeof(mon),1,fo);
    cout << "Tip: " << a.type << " opt.: " << a.opt << " rozn: " << a.rozn << endl;
    fclose(fo);
}
 
void ClearFile()
{
    FILE *fo;
    clrscr();
    if ((fo=fopen("D:\\out.dat","wb"))==0){
    cout << "Error open output file!!!"<<endl;
      return ;}
    fclose(fo);
}
 
void Opt()
{
  mon a;
  FILE *fo;
 
  if ((fo=fopen("D:\\out.dat","r"))==0){
    cout << "Error open output file!!!";
    return;}
  fseek(fo,0,SEEK_SET);
   int res;
  cout << "Vvedite optovuy cenu: " << endl;
  cin >> p;
   do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
  fclose(fo);
   return;
}
void Rozn()
{
  mon a;
  FILE *fo;
  if ((fo=fopen("D:\\out.dat","r"))==0){
    cout << "Error open output file!!!";
    return;}
  fseek(fo,0,SEEK_SET);
   int res1;
  cout << "Vvedite roznichnuy cenu: " << endl;
  cin >> v;
   do
   {
   res1=fread(&a,sizeof(mon),1,fo);
    if (a.rozn==v)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res1==1);
  fclose(fo);
   return;
}
void Search()
{
 char menu_2;
 do
 {
   cout <<endl<< "1 Optovaya" << endl << "2 Roznica" << endl << "3 Vozvrat v gl. menu"<< endl;
   menu_2=getch();
   switch(menu_2)
   {
     case '1':
       Opt();
       break;
     case '2':
       Rozn();
       break;
      };
   if (menu_2=='3') break;
 }
 while(1);
clrscr();
}
 
void main()
{
 char menu;
 int i;
 kol=0;
 clrscr();
 do
 {
   cout <<endl<< "1 Zapis' v file" << endl <<"2 Vivod na ekran" << endl << "3 Ochistka file" << endl << "4 Search..."<< endl << "5 Vichod" << endl;
   menu=getch();
   switch(menu)
   {
     case '1':
       WriteFile();
       break;
     case '2':
       out();
       break;
     case '3':
       ClearFile();
       break;
     case '4':
       Search();
       break;
         };
   if (menu=='5') break;
 }
 while(1);
}
accept
4819 / 3239 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.04.2009, 00:13     Нужна помощь в исправлении кода одной функции... #11
Код
    cout << "Vvedite optovuy cenu: " << endl;
    cin >> p;
надо p создать, если вводишь внутри, то создавай внутри int p;
когда у тебя формат ввода вынесен в отдельную функцию, её можно менять, это гораздо проще, чем лазить по всей функции, где всего лишь используется результат этого ввода, это выглядело бы как

Код
    Opt(EnterOptFloor());
или

Код
    int floor;    
    
    if ((floor = EnterOptFloor()) > 0)
        Opt(floor);
сразу тогда можно встраивать проверку введённых данных в ту функцию ввода
а так, тебе приходится вводом заниматься в той функции, которая к нему вообще отношения не имеет
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
13.04.2009, 00:32  [ТС]     Нужна помощь в исправлении кода одной функции... #12
объясни пожалуйста поподробней как это решает мою проблему с этими смайликами и последней записью, которые выводится два раза... а то если честно я даже не понял куда нужно добавить то что ты написал...
accept
4819 / 3239 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.04.2009, 01:00     Нужна помощь в исправлении кода одной функции... #13
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Opt(void)
{
    FILE *fi;
    int res, p;
    mon a;
  
    if ((fi = fopen("D:\\out.dat", "rb")) == 0) {
        cout << "Error open output file!!!";
        return;
    }
    fseek(fi, 0, SEEK_SET);
    cout << "Vvedite optovuy cenu: " << endl;
    cin >> p;
    while ((res = fread(&a, sizeof(mon), 1, fi)) == 1);
        if (a.opt == p)
            cout << a.type
                 << " "
                 << a.opt
                 << " "
                 << a.rozn
                 << " "
                 << a.comm
                 << " "
                 << endl;
    fclose(fi);
}
юзай такую

Цитата Сообщение от kandrey58region
1) в конце каждой записи стоит смайлик (улыбающаяся рожица)...
в конце каждой записи где ?

Добавлено через 2 минуты 42 секунды
ещё двоичный режим для файла b
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
13.04.2009, 01:33  [ТС]     Нужна помощь в исправлении кода одной функции... #14
прога то у меня работает, самое обидное ведь она и раньше работало, просто очистка экрана 'clrscr' стирала мой результат и выводила опять меню
Код
Huindai             350  400  plohoi                                  l
Samsung             500  550  norma                                   l
Sony                300  400  rtye                                    l
Acer                200  350  hgfak                                   l
т.е. при запросе оптовая цена ==500 на экран выводится
Код
Samsung             500  550  norma                                   :)
только смайлик черно-белый, палочка на конце каждой строки не влияет ни на что пробовал её убрать все равно тоже самое получается...
accept
4819 / 3239 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.04.2009, 04:10     Нужна помощь в исправлении кода одной функции... #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void WriteFile()
{
    FILE *fi,*fo;
 
    clrscr();        
        
        ...
 
        while (fgets(s, dl, fi)) {
        strncpy(a.type, s, 19);
            a.type[19] = '\0';
        a.opt = atoi(&s[20]);
            a.rozn = atoi(&s[25]);
            strncpy(a.comm, &s[30], 40);
        fwrite(&a, sizeof(mon), 1, fo);
            kol++;
    };
докуда strncpy(a.comm, &s[30], 40); будет читать ?

Добавлено через 9 минут 46 секунд
C++
1
2
        strncpy(a.comm, &s[30], 39);
        a.comm[39] = '\0';
kandrey58region
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 109
13.04.2009, 09:49  [ТС]     Нужна помощь в исправлении кода одной функции... #16
accept, спасибо проблема со смайликами решилась...
теперь осталась одна проблема с последней записью которая выводиться на экран дважды...
Evg
Эксперт CАвтор FAQ
17385 / 5623 / 350
Регистрация: 30.03.2009
Сообщений: 15,402
Записей в блоге: 26
13.04.2009, 12:53     Нужна помощь в исправлении кода одной функции... #17
C++
1
2
3
4
5
6
7
8
9
   do
   {
   res=fread(&a,sizeof(mon),1,fo);
    if (a.opt==p)
    {
      cout<<a.type<<" "<<a.opt<<" "<<a.rozn<<" "<<a.comm<<" "<<endl;
    }
   }
   while(res==1);
Проблема всё там же. Когда файл у тебя закончился, то fread вернул 0. Но вне зависимости от этого ты всё равно делаешь проверку a.opt с дальнейшей печатью. В тот момент, когда fread вернул 0, он из файла ничего не прочилал, а в переменной 'a' отсались старые значения с предыдущей итерации цикла. В посте #9 тебе уже написали готовое решение, как побороть эту проблему
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.04.2009, 23:51     Нужна помощь в исправлении кода одной функции...
Еще ссылки по теме:

C++ Нужна срочная помощь в исправлении программы, пожалуйста!)
C++ Нужна помощь с программой
Нужна помощь в прописании основной функции C++
C++ Нужна помощь в структуре поезд!
C++ Нужна помощь с программой

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4819 / 3239 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.04.2009, 23:51     Нужна помощь в исправлении кода одной функции... #18
Нужна помощь в исправлении кода одной функции...
цикл и правильное название для файлового указателя
Yandex
Объявления
13.04.2009, 23:51     Нужна помощь в исправлении кода одной функции...
Ответ Создать тему
Опции темы

Текущее время: 13:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru