Структуры и работа с ними

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ph0en1x, 23 Feb 2008.

  1. ph0en1x

    ph0en1x Elder - Старейшина

    Joined:
    14 Jun 2006
    Messages:
    29
    Likes Received:
    2
    Reputations:
    0
    Вот пишу лабораторку и мне необходимо записать структуру в файл, потом прочесть её и произвести поиск по отдельным перменным.
    погите с записью (чтением) структуры в (из) файла
     
  2. zythar

    zythar Elder - Старейшина

    Joined:
    16 Feb 2008
    Messages:
    517
    Likes Received:
    109
    Reputations:
    5
    write(дескриптор_файла, &структура, sizeof структура)
    read(дескриптор_файла, &структура, sizeof структура)

    вроде так.
     
  3. Delimiter

    Delimiter Banned

    Joined:
    8 Apr 2005
    Messages:
    317
    Likes Received:
    173
    Reputations:
    12
    CFile f;
    CFileException e;

    struct mt
    {
    ....
    ....
    } mtu;

    f.write((char *)&mtu,sizeof(mt));

    f.read((char *)&mtu,sizeof(mt));

    Edited: Пива было много.... поэтому чипатал левой ногом.
     
    #3 Delimiter, 24 Feb 2008
    Last edited: 24 Feb 2008
  4. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    давайте щас еще понтоваться кто как умееть писать в файл +)
    пусть автор уточнит как он производит запись. но абстрактно это можно выразить так, как сказал zythar

    это раз.. два: Delimiter, как ты собрался брать АДРЕС СТРУКТУРЫ? Поясни-ка поподробнее..
     
  5. ph0en1x

    ph0en1x Elder - Старейшина

    Joined:
    14 Jun 2006
    Messages:
    29
    Likes Received:
    2
    Reputations:
    0
    я сам толком не знаю как я произвожу запись :confused:
    вобщем ситуация следующяя:
    У меня есть структура
    Code:
    struct MYSTRUCTURE {
      	char city[20];
      	char otp[5];
      	int number;
      	char time[5];
      	int mest;
      	};
    Мне нада ввести с терминала данные в елементы структуры и записать всё это безобразие в файл, таким образом чтоб я мог потом его
    открыть и произвести поиск по елементам city и otp, запрос для поиска тоже должен вводится с клавиатуры.
    Количество записей в файле должно быть произвольное. И желательно это всё запихнуть в одну программу т.е. сначала вводим эти записи потом какойнибудь стоп символ вводится, данные записываются, потом читаются и работа с поиском.
     
    #5 ph0en1x, 24 Feb 2008
    Last edited: 24 Feb 2008
  6. zythar

    zythar Elder - Старейшина

    Joined:
    16 Feb 2008
    Messages:
    517
    Likes Received:
    109
    Reputations:
    5
    ну хз.. структуру объявил, потом объяви переменную типа структуры:
    struct MYSTRUCTURE foo;

    присвой элементам структуры значения сам, в исходном файле, потом открой файл, и записивай в него или так как я сказал или как delimiter.
    если все хорошо пойдет то тогда уже вводи значения елементов структуры из терминала.
     
  7. nc.STRIEM

    nc.STRIEM Members of Antichat

    Joined:
    5 Apr 2006
    Messages:
    1,036
    Likes Received:
    347
    Reputations:
    292
    сохраняй каждый элемент структуры с новой строки и все...
     
  8. ph0en1x

    ph0en1x Elder - Старейшина

    Joined:
    14 Jun 2006
    Messages:
    29
    Likes Received:
    2
    Reputations:
    0
    хм и что это получится если записей будет много?

    Вот так получилось, но не знаю можно ли так:
    Code:
    #include <iostream.h>
    #include <string.h>
    #include <stdio.h>
    struct MYSTRUCTURE {
    	char city[20];
    	char otp[5];
    	int number;
    	char r[5];
    	int mest;
    	};
    
    main() {
        MYSTRUCTURE MyStructure;
    	strcpy(MyStructure.city, "Moscov" );
    	strcpy(MyStructure.otp, "10:25");
    	strcpy(MyStructure.r, "16:25");
    	MyStructure.mest = 20;
    	MyStructure.number =1112;
    	freopen("aeroflot.txt", "rt", stdout);
    	cout << "|";
    	cout << MyStructure.number;
    	cout << "|";
    	cout << MyStructure.city;
    	cout << "|";
    	cout << MyStructure.otp;
    	cout << "|";
    	cout << MyStructure.r;
    	cout << "|";
    	cout << MyStructure.mest;
    	cout << "|" << endl;
    	return 0;
    	}
    П.С. чуть упростил задачю т.к. меня интересует пока только запись в файл ввод переменных через присваивание, и копирование.
     
    #8 ph0en1x, 24 Feb 2008
    Last edited: 24 Feb 2008
  9. nc.STRIEM

    nc.STRIEM Members of Antichat

    Joined:
    5 Apr 2006
    Messages:
    1,036
    Likes Received:
    347
    Reputations:
    292
    все норм получиться, каждый элемент с новой строки, и так любое кол-во. Загружать также. Все элементарно
     
  10. ph0en1x

    ph0en1x Elder - Старейшина

    Joined:
    14 Jun 2006
    Messages:
    29
    Likes Received:
    2
    Reputations:
    0
    Code:
    #include <iostream.h>
    #include <fstream.h>
    struct MYSTRUCT {
    	char city[20];
    	char otp[5];
    	int number;
    	char r[5];
    	int mest;
    	};
    int main(void){
        int i;
        struct MYSTRUCT s[200];
        ofstream mystream_out("aeroflot.txt", ios::in|ios::out);
        if (!mystream_out)
        {
        cout << "Cannot open file.\n";
        return 1;
        }
        else{
    for(i=1; i<=2; i++){
        cout<< "\nZapus" <<("%2.d",i);
        cout<< ("\nCity"); cin >> s[i].city;
        }
        mystream_out.write((char*)s, sizeof(s));
        mystream_out<< &s <<endl;
        mystream_out.close();
        }
    return 0;
    }
    чуствую что гдето ошибся ибо открыв файл получаю вместо двух слов много сиволов разных.
    Это так и должно быть или я всётаки ошибся?
     
    #10 ph0en1x, 24 Feb 2008
    Last edited: 24 Feb 2008
  11. zythar

    zythar Elder - Старейшина

    Joined:
    16 Feb 2008
    Messages:
    517
    Likes Received:
    109
    Reputations:
    5
    а почему у тебя массив структур то?
    делай одну структуру а не массив. потом присваивай значения элементам структуры, потом открывай файл и в него пиши. что ты там написал я не разобрался. лучше используй не с++ а си. в си все намноге проще и яснее
     
    #11 zythar, 24 Feb 2008
    Last edited: 24 Feb 2008
  12. nc.STRIEM

    nc.STRIEM Members of Antichat

    Joined:
    5 Apr 2006
    Messages:
    1,036
    Likes Received:
    347
    Reputations:
    292
    Code:
    #include <stdio.h>
    
    struct MYSTRUCT {
    	char city[20];
    	char otp[5];
    	int number;
    	char r[5];
    	int mest;
    	};
    	
    int main(void)
    {
        int KolEl;
     ///// .......  определяемся c кол-вом элементов
        MYSTRUCT *dan= new MYSTRUCT[KolEl];
        
    	/* тут ввод данных
    	..................
    	*/
    	
    	//сохраняем
    	FILE *fw;
    	fw = fopen("save.txt", "wb");
    	for(int i=0; i<KolEl; i++)
    		fprintf(fw, "%s\n%s\n%d\n%s\n%d\n", dan[i].city, dan[i].otp, dan[i].number, dan[i].r, dan[i].mest,);
    	fclose(fw);
    	return 0;
    }
     
    1 person likes this.
  13. Forcer

    Forcer Elder - Старейшина

    Joined:
    12 Apr 2007
    Messages:
    321
    Likes Received:
    98
    Reputations:
    12
    ph0en1x
    Держи рабочий вариант:

    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    struct MYSTRUCT {
    	char city[20];
    	char otp[5];
    	int number;
    	char r[5];
    	int mest;
    };
    
    void setStructVals(struct MYSTRUCT &);
    void svStrToFile(const struct MYSTRUCT &, fstream &);
    void prtStr(const struct MYSTRUCT &);
    
    int main()
    {
    	const char ifile[] = "aeroflot.txt";
    	struct MYSTRUCT* myptr = 0;
    	int size = 0;
    
    	// узнаём у пользователя, сколько он хочет ввести структур
    	cout << "Number of structurs : ";
    	cin >> size;
    
    	//  выделяем память и проверяем, выделилась ли она
    	myptr = new struct MYSTRUCT[size];
    
    	if( myptr == 0 ) {
    		cerr << "Not enougth memory" << endl;
    		return 1;
    	}
    
    	// открываем файл, делаем проверку открытия
    	fstream file(ifile, ios::binary | ios::in | ios::out | ios::trunc);
    	
    	if( file.fail() ) {
    		cerr << "Cant open file" << endl;
    		return 1;
    	}
    
    	// предоставляем пользователю возможность ввести значения для структур, сразу же сохраняя в файл
    	for(int i=0; i < size; ++i) {
    		cout << "\tNew struct : " << endl;
    		setStructVals(myptr[i]);
    		svStrToFile(myptr[i], file);
    	}
    
    	// освобождаем память занятую структурами
    	// теперь структуры мы сможем получить только из файла
    	delete [] myptr;
    
    	// запрашиваем у пользователя данные для поиска
    	char city[20];
    	char otp[5];
    
    	cout << "\n\tFind struct:\nInput parametrs for struct : " << endl;
    	cout << "\ncity : ";
    	cin >> city;
    	cout << "otp : ";
    	cin >> otp;
    
    	struct MYSTRUCT tmp;
    
    	// осуществляем поиск по введённым значениям
    	for(int i=0; i < size; ++i) {
    		file.seekg(i * sizeof(tmp));
    		file.read((char*)&tmp, sizeof(tmp));
    
    		if( ( strcmp(tmp.city, city) && strcmp(tmp.otp, otp) ) == 0 ) {
    			cout << "Struct : " << endl;
    			prtStr(tmp);
    			// break;  // можно завершить поиск, либо искать дальше
    		}
    	}
    
    	cout << "\tsearch is ended" << endl;
    
    	// завершаем работу
    	file.close();
    
    	return 0;
    }
    
    void setStructVals(struct MYSTRUCT &str) {
    	cout << "city : ";
    	cin >> str.city;   // предполагается, что нет разделителей в названии города
    	cout << "otp : ";
    	cin >> str.otp;
    	cout << "number : ";
    	cin >> str.number;
    	cout << "r : " ;
    	cin >> str.r;
    	cout << "mest : ";
    	cin >> str.mest;
    }
    
    void svStrToFile(const struct MYSTRUCT &str, fstream &file) {
    	file.write((char*)&str, sizeof(str));
    }
    
    void prtStr(const struct MYSTRUCT &str) {
    	cout << "city : " << str.city << endl;
    	cout << "otp : " << str.otp << endl;
    	cout << "number : " << str.number << endl;
    	cout << "r : " << str.r << endl;
    	cout << "mest : " << str.mest << endl;
    }
    Замечание:
    Как правильно заметил zythar, для данной конкретной задачи не нужно использовать массив структур, достаточно одной стуктуры. При написании этого кода я упустил этот момент. Оставляю первоначальный вариант, так как он, мне кажется, больше соответствует названию темы.
     
    #13 Forcer, 24 Feb 2008
    Last edited: 25 Feb 2008
    1 person likes this.