1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
1

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

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

Author24 — интернет-сервис помощи студентам
Плиз.. помогите исправить код функции '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' в конце строки каждого файла ни имеет значения он просто показывает где заканчивается каждая строка.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.04.2009, 20:49
Ответы с готовыми решениями:

Нужна помощь в исправлении
эта программа расчитывает значения отрезка интегрирования (x1, x2) один для всех трех интегралов,...

Нужна срочная помощь в исправлении программы, пожалуйста!)
С клавиатуры вводится значения х и y. В зависимости от значений х и y рассчитать значение функции f...

Нужна помощь в поиске и исправлении бага
Здравствуйте. Задумал собрать и собрал 8x8x8 RGB LED Cube. Схему и прошивку взял у автора по...

Нужна помощь в исправлении ошибок в методах cтруктуры
Доброго времени суток, товарищи- программисты! Нужна помощь в исправлении ошибок в методах: в ...

17
577 / 571 / 65
Регистрация: 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.
1
176 / 168 / 27
Регистрация: 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 то где-то надо инициализировать
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.04.2009, 21:04 4
Переменная res так же не определена, а потому цикл наверняка окажется бесконечный, а файл при этом ограниченного размера, после чего начинается работа с залипшими данными от предыдущих итераций цикла

Добавлено через 1 минуту 20 секунд
Пардон, про res не заметил. Снимаю свою претензию
1
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
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);
помогите пожалуйста довести эту функцию до ума
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.04.2009, 21:45 6
Закомментируй строку 'if (a.opt==p)' и смотри, что печатает. Увидишь, что у тебя из файла реально программа читает и глазами хотябы оцени правильно это или нет
1
577 / 571 / 65
Регистрация: 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);
}
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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. Т.е. с этой точки зрения вроде бы как всё правильно (чтение и запись симметричны)
1
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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
1
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
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);
}
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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);
сразу тогда можно встраивать проверку введённых данных в ту функцию ввода
а так, тебе приходится вводом заниматься в той функции, которая к нему вообще отношения не имеет
1
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
13.04.2009, 00:32  [ТС] 12
объясни пожалуйста поподробней как это решает мою проблему с этими смайликами и последней записью, которые выводится два раза... а то если честно я даже не понял куда нужно добавить то что ты написал...
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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
1
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
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                                   :)
только смайлик черно-белый, палочка на конце каждой строки не влияет ни на что пробовал её убрать все равно тоже самое получается...
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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';
1
1 / 1 / 0
Регистрация: 11.03.2009
Сообщений: 107
13.04.2009, 09:49  [ТС] 16
accept, спасибо проблема со смайликами решилась...
теперь осталась одна проблема с последней записью которая выводиться на экран дважды...
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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 тебе уже написали готовое решение, как побороть эту проблему
1
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
13.04.2009, 23:51 18
https://www.cyberforum.ru/post136670.html
цикл и правильное название для файлового указателя
0
13.04.2009, 23:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.04.2009, 23:51
Помогаю со студенческими работами здесь

Нужна помощь в исправлении схемы измерительного усилителя
Получилась после моделирования вот такая схема измерительного усилителя:...

Дерево .Помощь в исправлении ошибок
Доброе всем время суток! Написала дерево с функциями реализации: 1)Добавления элемента...

Помощь в исправлении ошибок в коде
NAK1 STORAGE 10 NAK2 STORAGE 10 NAK3 STORAGE 10 SIMULATE 5 GENERATE 10, 5 ADVANCE 10, 3 TEST...

Нужна помощь в написании кода
Есть документ в котором есть поля :Сотрудник(ссылка на справочник сотрудники),проект(ссылка на...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru