Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] Интерпретация данных для записи в файл


Автор: Night_xxx 30.3.2007, 18:33
Так у даны два типа данных char и int. Для записи в файд нужно интерпритировать все данные в тип char* . Значит надо интерпритировать тип int в char*. Я сделал, но у меня что-то неверно с интерпритайией, т.е. вводим:
Номер-------  0
Name--------  petr
Age----------- 18

И в файл записывается:
petr                0               //Т.е. тип int я неправильно интерпритировал

Подскажите как надо плиз


Код

#include "stdafx.h"
#include <iostream.h>
#include "iomanip.h"
#include <stdio.h>
#include <fstream.h>

int get_int(int default_value);
char name[20];
int age;

int main() 
{
    char filename[81];
    int n;
    char ch='y';
    
    int recsize=sizeof(name)+sizeof(int);
    
    printf("Vvedite imya faila dla zapisi: ");
    gets(filename);
    
    fstream fbin(filename, ios::binary| ios::in| ios::out);
    if(!fbin)
    {
        cout<<"\aFail "<<filename<<" ne bil uspershno otkrit";
        return -1;
    }
    
    while(ch=='y')
    {
        cout<<"Vvedite nomer kuda budem vpicivati dannie: "; 
        cin>>n;
        
        printf("Enter name: ");
        gets(name);
        printf("Enter age: ");
        cin>>age;
        
        fbin.seekp(n*recsize);
        fbin.write(name,20);
        fbin.write(reinterpret_cast<char*>(&age),sizeof(int));
        cout<<"Prodoljim? (y/n)"; cin>>ch;
    }
    
    fbin.close();
    return 0;
}

Автор: zkv 30.3.2007, 18:55
почему оператор << не используете?
Код

fbin<<age;
 
ну если все таки по вашему:
Код

        ostrstream str;
        str<<age<<'\0';
        fbin.write(str.str(), strlen(str.str() ) );

также можно использовать itoa() или sprintf()

а reinterpret_cast<char*>(&age) просто говорит о том, чтобы рассматривать данные, лежащие по адресу переменной age как массив символов, что не является конвертацией

Автор: Night_xxx 30.3.2007, 19:19
Так напигите мне полностью рабочую программу, а то я че то не догоняю. 
Я написал как было написано в книге, если что-то неправильно так исправьте мне чтобы все работало

Автор: Night_xxx 30.3.2007, 19:51
Так что никто не может написать мне чтоб все правильно записывало???????????!!!!!!!

Автор: Xenon 30.3.2007, 20:16
По идее так:
Код

int get_int(int default_value);
char name[20];
int age;

int main() 
{
    char filename[81];
    int n;
    char ch = 'y';
    
    int recsize=sizeof(name)*sizeof(char)+sizeof(int);
    
    printf("Vvedite imya faila dla zapisi: ");
    gets(filename);
    
    fstream fbin(filename, ios::binary | ios::in | ios::out);
    if(!fbin)
    {
        cout << "\aFail " << filename << " ne bil uspershno otkrit";
        return -1;
    }
    
    while(ch == 'y')
    {
        cout << "Vvedite nomer kuda budem vpicivati dannie: "; 
        cin >> n;
        
        printf("Enter name: ");
        gets(name);
        printf("Enter age: ");
        cin >> age;
        
        fbin.seekg(n*recsize);
        fbin.write(name,sizeof(char)*20);
        fbin.write(reinterpret_cast<char*>(&age),sizeof(int));
        cout << "Prodoljim? (y/n)"; cin >> ch;
    }
    fbin.close();
    return 0;
}


Автор: Night_xxx 30.3.2007, 20:45
Xenon,  все осталось так как есть, например вводим:
Введите номер записи -------- 0
Введите имя --------------------- name
Введите age --------------------- 18

И в итоге в файле видим следующее:
name                0       ////////////////////и так далее всегда на месте где должно было быть значение age выходит 0 

Так все тип int почему неправильно интерпретируется....
Вопрос все ещё открыт.  Что же я делаю не так???

Автор: Xenon 30.3.2007, 20:51
Night_xxx, Ты как считываешь? Код в студию. Если ты открываешь файл в текстовом в редакторе, то ... да ...

Автор: Night_xxx 30.3.2007, 21:17
А какая разница где открывать , главное что все таки в них записывается?
Так что 
Xenon,  у тебя так как надо выходит в редакторе (куда записывали age записано нужное значение)?


Так если записывали значение с типом char все ведь правильно записывается. Поясни подробнее в чем дело в моей программе(почему всегда на месте куда записывали age находятся нули) . Че то я нихрена не понял

Автор: zkv 30.3.2007, 21:21
Цитата(Night_xxx @  30.3.2007,  20:45 Найти цитируемый пост)

Так все тип int почему неправильно интерпретируется....

нет, как раз интерпретируется он правильно, как массив байтов, может вы хотите преобразовать из int в char? Но в этом случае ваш алгоритм не будет работать, или его придется немного модифицировать.

Автор: Night_xxx 30.3.2007, 21:24
Да я хочу тип int преобразовать в char.  И как правильно модифицировать. Напишите полностью рабочую программу, чтобы работала как надо. 

Автор: Xenon 30.3.2007, 21:26
Поскольку char рассматривается как char при записи, то в файле его ты видишь нормально, а int когда рассматриваешь как char и пишешь в файл, то сам понимаешь, что фиг знает как нарезаный int может выглядеть там как угодно. Тебе нужно все вернуть назад, то есть не в редакторе читать, а в программе читать. Ты же бинарно пишешь.
Код

fbin.read(name,sizeof(char)*20);
fbin.read(reinterpret_cast<char*>(&age),sizeof(int));

Автор: Dov 30.3.2007, 21:37
Цитата(Night_xxx @  30.3.2007,  21:24 Найти цитируемый пост)
Напишите полностью рабочую программу, чтобы работала как надо. 


Night_xxx, если ты хочешь, что бы тебе помогли, то посиди минут 10, подумай спокойно, сформулируй задачу, ибо я, например, уже часа 2 наблюдаю за твоей перепиской и до сих пор ни фуя не понял: 
1. зачем ты пишешь в бинарный  файл, а не в текстовый?
2. зачем int в char переводить?
3. зачем printf, gets, cout, cin и т.д. всё вместе перемешано?
Ну, и так далее...

Автор: Night_xxx 30.3.2007, 22:27
Так в начале отвечу 
Dov,  
1)пишу в бинарный файл, т.к. потом мне будет легче искать там нужные значения (а тут я только выложил непонятную мне часть програмки);
2)перевожу int в char так как у меня есть ещё тип int в условии (для поля age) , и я прочитал в книге чтобы привести тип int к типу char необходимо использовать оператор reinterpret<char*>
А вообще это приведение необходимо так как при работе с двоичными файлами нужен только тип char*
3)А что в этом такого!!!!!!!!!!!!!!!!!


Ну теперь ладно видимо так кашу не сваришь, вообщем я продвинулся дальше и теперь изложу следующее событие, вызывающее у меня непонимание:

Вначале программа:

Код

#include "stdafx.h"
#include <iostream.h>
#include "iomanip.h"
#include <fstream.h>
#include "string.h"
#include "stdlib.h"
#include "conio.h"

void zapici();
void chtenie();
void menu();

    char filename[81];
char name[20];
char age[2];
int recsize=sizeof(name)+sizeof(age);

int main() {
    
    char ch1='y', ch2='y';
        
    printf("Vvedite imya faila dla zapisi: ");
    gets(filename);

    fstream fbin(filename, ios::binary| ios::in| ios::out);
    if(!fbin)
    {
        cout<<"\aFail "<<filename<<" ne bil uspershno otkrit";
        return -1;
    }

    menu();

    fbin.close();
    return 0;
}

void menu()
{
    system ("cls");
    int k;
cout<<"\n\n\t\t*************MENU**************";
    cout<<"\n\n\t\tZapicati v fail   ------ PRESS 1"; 
    cout<<"\n\n\t\tProchitati zapici ------ PRESS 2"; 
    cout<<"\n\n\t\tViiti iz programmi------ PRESS 3";
    cout<<"\n\n\t\tVash vibor  ";cin>>k;
    switch(k)
    {
    case 1: zapici();
    case 2: chtenie();
    case 3: exit(0);
    }
}

void zapici()
{
    fstream fbin(filename, ios::binary| ios::in| ios::out);
    char ch1='y';
int n;
while(ch1=='y')
    {
        cout<<"\nVvedite nomer dla zapici "; cin>>n;
        printf("Name - "); gets(name);
        printf("Age - "); cin>>age;
        fbin.seekp(n*recsize);
        fbin.write(name,20);
        fbin.write(age,2);
        cout<<"Prodoljiti? (y/n)"; cin>>ch1;
        if(ch1!='y') {menu();}
    }
}

void chtenie()
{
    fstream fbin(filename, ios::binary| ios::in| ios::out);
    char ch2='y';
    int n;

    while(ch2=='y'){
    cout<<"\nVvedite nomer otkuda budem 4itati dannnie: "; 
    cin>>n;
    fbin.seekp(n*recsize);

    fbin.read(name,20);
    fbin.read(age,2);
    cout<<"Name - "<<name<<endl;
    cout<<"Age - "<<age<<endl;
    cout<<"Prodoljim? (y/n)"; cin>>ch2;
    if(ch2!='y') {menu();}
    }
}



Теперь что мне непонятно:
Вводим:
Имя файла ----------  fail
Вначале в меню выбираем записать значения (1)
Номер записи--------- 0
Name-------------------- name
Age---------------------- 13
Продолжаем
Номер записи--------- 1
Name-------------------- nameeeee
Age---------------------- 15
Продолжаем
Номер записи--------- 2
Name-------------------- nameeeeeeeeee
Age---------------------- 18
Выходим в меню
Выбираем чтение
Прочитать запись ----0
Все правильно вывелось
Прочитать запись-----1
Все правильно вывелось
Прочитать запись-----2
И как ни странно я не нахожу тут своей последней записи, вместо этого выходит запись 1.
Вообщем последняя запись не записывается, а почему?????????? Ответьте мне на этот вопрос ответом, а ни приветом



Автор: Xenon 30.3.2007, 22:50
У тебя вообще сплошная жесть, а не код. Мешать стиль - плохой тон. Ты либо в С++ пиши, либо уж в С, а то такую мешанину читать не очень удобно.
Потом, ты определяешь новую переменную fstream fbin(filename, ios::binary| ios::in| ios::out); и открываешь файл, затем в zapici() ты опять открываешь тот же файл. Зачем создавать переменную на чтение/запись, если ты либо читаешь, либо пишешь ...
Тут может быть что угодно, вплоть до того, что у тебя файл старый с данными уже записаными перезаписынами вкривь и вкось.
PS. Что за цикл switch без break`ов?

Автор: Night_xxx 30.3.2007, 23:00
Да теперь я понял что ты 
Xenon,  объяснил мне насчет приведения типа int в char. С этим все ясно.

Но как и с первым случаем когда я age использую как тип int так и по-другому, когда я исрользую age в типе char
При записи последняя запись не записывается !!!!!!!! 
Ну напишите мне мой последний выложенный вариант правильно, чтобы все записывалось.
Ну а насчет смешения стилей я ни думал что как-то может повлиять на правильность программы.
Ну все таки исправьте мой последний код правильно или укажите точно на мою ошибку.

Автор: Xenon 30.3.2007, 23:14
Night_xxx, переписал ... У тебя жутко спроектировано, если честно ... Задумайся smile Хотя бы обрати внимание на циклы опроса пользователя - do { ... } while(...); У тебя там очень своеобразная логика smile
PS. А чего тебе мешает пользоваться string?
Код

#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>

void write();
void read();
void menu();

char filename[81];
int recsize = 20*sizeof(char)+sizeof(int);

using std::cout;
using std::cin;
using std::fstream;
using std::ios;
using std::endl;

fstream fbin;

int main() 
{     
    printf("Vvedite imya faila dla zapisi: ");
    cin.getline(filename,80);
    fbin.open(filename, ios::binary | ios::in | ios::out);
    if(!fbin)
    {
        cout << "\aFail " << filename << " ne bil uspershno otkrit";
        return -1;
    }
    menu();
    fbin.close();
    return 0;
}

void menu()
{
    system ("cls");
    int choice = 0;
    cout << "\n\n\t\t*************MENU**************";
    cout << "\n\n\t\tZapicati v fail   ------ PRESS 1"; 
    cout << "\n\n\t\tProchitati zapici ------ PRESS 2"; 
    cout << "\n\n\t\tViiti iz programmi------ PRESS 3";
    cout << "\n\n\t\tVash vibor  ";
    cin >> choice;
    switch(choice)
    {
    case 1: write();
        break;
    case 2: read();
        break;
    case 3: exit(0);
        break;
    default:cout << "Nepravilnij vibor";
        break;
    }
}

void write()
{
    char choice = 'y';
    int n;
    char name[20];
    int age;
    do
    {
        cout << "\nVvedite nomer dla zapici ";
        cin >> n;
        cout << "Name - "; 
        cin >> name;
        cout << "Age - "; 
        cin >> age;
        fbin.seekg(recsize*n,ios::beg);
        fbin.write(name,sizeof(char)*sizeof(name));
        fbin.write(reinterpret_cast<char*>(&age),sizeof(int));
        fbin.clear();
        cout << "Prodoljiti? (y/n)"; 
        cin >> choice;
    }while(choice != 'n');
    menu();
}

void read()
{
    char choice = 'y';
    char name[20];
    int age;
    int n;
    do
    {
        cout << "\nVvedite nomer otkuda budem 4itati dannnie: "; 
        cin >> n;
        fbin.seekg(n*recsize,ios::beg);
        fbin.read(name,sizeof(char)*sizeof(name));
        fbin.read(reinterpret_cast<char*>(&age),sizeof(int));
        fbin.clear();
        cout << "Name - " << name << endl;
        cout << "Age - " << age << endl;
        cout << "Prodoljim? (y/n)"; 
        cin >> choice;
    }while(choice != 'n');
    menu();
}

Автор: Night_xxx 31.3.2007, 00:58
Все спасибо тебе 
Xenon,  А вообще у меня был готовый вариант в книжке, но я сам по своему хотел написать. Все таки когда все сам делаешь, то очень многому учишься. 

Автор: Xenon 31.3.2007, 01:24
Не за что - учись smile
Единственное, мне еще вызов функции menu() не нравится. Я думаю, лучше так:
Код

#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>

void write();
void read();
void menu();

char filename[81];
int recsize = 20*sizeof(char)+sizeof(int);

using std::cout;
using std::cin;
using std::fstream;
using std::ios;
using std::endl;

fstream fbin;

int main() 
{     
    printf("Vvedite imya faila dla zapisi: ");
    cin.getline(filename,80);
    fbin.open(filename, ios::binary | ios::in | ios::out);
    if(!fbin)
    {
        cout << "\aFail " << filename << " ne bil uspershno otkrit";
        return -1;
    }
    menu();
    fbin.close();
    return 0;
}

void menu()
{
    int choice = 0;
    do
    {
        system ("cls");
        cout << "\n\n\t\t*************MENU**************";
        cout << "\n\n\t\tZapicati v fail   ------ PRESS 1"; 
        cout << "\n\n\t\tProchitati zapici ------ PRESS 2"; 
        cout << "\n\n\t\tViiti iz programmi------ PRESS 3";
        cout << "\n\n\t\tVash vibor  ";
        cin >> choice;
        switch(choice)
        {
        case 1: write();
            break;
        case 2: read();
            break;
        case 3:break;
        default:cout << "Nepravilnij vibor";
            break;
        }
    }while(choice !=3);
}

void write()
{
    char choice = 'y';
    int n;
    char name[20];
    int age;
    do
    {
        cout << "\nVvedite nomer dla zapici ";
        cin >> n;
        cout << "Name - "; 
        cin >> name;
        cout << "Age - "; 
        cin >> age;
        fbin.seekg(recsize*n,ios::beg);
        fbin.write(name,sizeof(char)*sizeof(name));
        fbin.write(reinterpret_cast<char*>(&age),sizeof(int));
        fbin.clear();
        cout << "Prodoljiti? (y/n)"; 
        cin >> choice;
    }while(choice != 'n');
}

void read()
{
    char choice = 'y';
    char name[20];
    int age;
    int n;
    do
    {
        cout << "\nVvedite nomer otkuda budem 4itati dannnie: "; 
        cin >> n;
        fbin.seekg(n*recsize,ios::beg);
        fbin.read(name,sizeof(char)*sizeof(name));
        fbin.read(reinterpret_cast<char*>(&age),sizeof(int));
        fbin.clear();
        cout << "Name - " << name << endl;
        cout << "Age - " << age << endl;
        cout << "Prodoljim? (y/n)"; 
        cin >> choice;
    }while(choice != 'n');
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)