Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/46: Рейтинг темы: голосов - 46, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 09.02.2011
Сообщений: 25
1

Файловый ввод/вывод

09.02.2011, 17:43. Показов 8235. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Ребят, не могу никак понять файловый ввод вывод текстовой информации в с++. Знаю сто открытие через fopen, а как создать сам текстовый файл в самой с++, а потом его считать?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.02.2011, 17:43
Ответы с готовыми решениями:

Заменить в программе, переводящую строку в двоичный код, консольный ввод/вывод на файловый ввод/вывод
Добрый день! Помогите, пожалуйста, с программой. Программа считывает строку с клавиатуры и...

Поменять консольный ввод-вывод на файловый ввод-вывод
вот у меня калькулятор как мне сделать что б числа вводились из файла и результат записывался в...

Файловый ввод-вывод, ввод с клавиатуры и обработка массива структур
Добрый вечер)) У меня небольшой вопрос. Почему первые буквы (в названии книг) не выводит на экран?...

Реализовать вывод массива объектов типа Student на консоль (файловый ввод/вывод)
Как сделать чтобы список студентов выводился на экран в конце? #include<iostream> ...

15
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.02.2011, 18:24 2
Давайте определимся, что вы хотите: C или C++. fopen() - это функция C. Прототип выглядит так:

C
1
FILE * fopen ( const char * filename, const char * mode );
filename - имя файла
mode - режим. Выглядит как C-строка (массив char с нуль-терминатором в конце). Может иметь значения:
"r"Чтение. Файл должен существовать.
"w"Запись с перезаписью. Если файл не существует, он создаётся.
"a"Запись с дописыванием в конец. Если файл не существует, он создаётся.
"r+"Чтение-запись. Файл должен существовать.
"w+"Чтение-запись с перезаписью. Если файл не существует, он создаётся.
"a+"Чтение-запись с дописыванием в конец. Если файл не существует, он создаётся.

Чтение в стиле C:

C
1
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Чтение из stream элементов данных в количестве не более nmemb (каждый размером в size байт) в область памяти, указанную ptr;

Запись в стиле C:

C
1
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
Запись в stream элементов данных в количестве nmemb (каждый размером в size байт) из области памяти, указанной ptr;

Обе функции возвращают количество записанных данных.

Вот пример программы (используя вызовы C):

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
#include <stdio.h>
 
void write( const char * fileName );
void read( const char * fileName );
 
int main()
{
    write( "test_file.txt" );
    read( "test_file.txt" );
 
    return 0;
}
 
void write( const char * fileName )
{
    const char * data = "Hello, world!"; //14 байт (учитывая 0x00 в конце)
    FILE * myFile = fopen( fileName, "w" );
 
    if( myFile == 0 )
    {
       printf( "Error opening %s for writing.\n", fileName );
       return;
    }
 
    int wrote = fwrite( data, sizeof(char), 14, myFile );
    printf( "Wrote %i bytes\n", wrote );
 
    fclose( myFile );
}
 
void read( const char * fileName )
{
    char data[255] = {0};
 
    FILE * myFile = fopen( fileName, "r" );
 
    if( myFile == 0 )
    {
       printf( "Error opening %s for reading.\n", fileName );
       return;
    }
 
    int read = fread( data, sizeof(char), 254, myFile );
    printf( "Read %i bytes:\n%s\n", read, data );
 
    fclose( myFile );
}
C-компилятор может не компилировать, я использовал C++-компиллер.

Но если вы хотите C++, используйте потоки файлового вывода-вывода (ifstream - ввод, ofstream - вывод, fstream - ввод и вывод). Подробнее тут: Чем отличается fstream от ofstream?

Удачи.
2
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
09.02.2011, 23:03 3
Хорошо написал. Спасибо.
0
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 04:01 4
Подниму тему, дабы не плодить.
Разбираюсь в потоках.
Объясните пожалуйста, что не так в фукции read()?
write() пишет в файл все на ура. По крайней мере, размер файла соответствует тому, сколько объектов в него записано.
А вот чтение не проходит. Прям беда. Притом ошибка происходит уже после выполнения if(inFile.eof())
код, собственно:
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
void Distance::write()
{
    ofstream outFile;
    outFile.open("DIST.DD", ios::trunc|ios::binary);
    if(!outFile)
    {cerr << "\nНевозможно открыть файл для записи данных.\n"; _getch(); exit(1);}
 
    for(int i=0; i<count; i++)
    {
        outFile.write((char*)(arrap[i]), sizeof(Distance));
    }
    if(!outFile)
    {cerr << "\nЗапись в файл невозможна.\n"; _getch(); exit(1);}
    outFile.close();
}
 
void Distance::read()
{
    ifstream inFile;
    inFile.open("DIST.DD", ios::binary);
    if(!inFile)
    {cerr << "\nНевозможно открыть файл для чтения данных.\n"; _getch(); exit(1);}
    int i=0;
    while(true)
    {
        arrap[i] = new Distance;
        inFile.read((char*)arrap[i], sizeof(Distance));
        if(inFile.eof())
            break;
        i++;
    }
    if(!inFile)
    {cerr << "\nНевозможно произвести чтение из файла.\n"; _getch(); exit(1);}
    inFile.close();
}
Уже даже не знаю что и думать. Где -то завис.
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.02.2011, 11:36 5
Так работает:

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
#include <iostream>
#include <fstream>
#include <string.h>
 
using namespace std;
 
const int count = 15;
 
struct Distance
{
    int x, y;
}
* arrap[ count ];
 
 
void write()
{
    ofstream outFile;
    outFile.open("DIST.DD", ios::trunc|ios::binary);
    if(!outFile)
    {
        cerr << "\nCould not open for writing.\n";
        return;
    }
 
    for(int i=0; i<count; i++)
    {
            outFile.write((char*)(arrap[i]), sizeof(Distance));
    }
 
    if(!outFile)
    {
        cerr << "\nWrighting is impossible.\n";
        return;
    }
    outFile.close();
 
}
 
void read()
{
    ifstream inFile;
    inFile.open("DIST.DD", ios::binary);
 
    if(!inFile)
    {
        cerr << "\nCould not open for reading.\n";
        return;
    }
 
    int i=0;
    while(true) //тут бы так: while( i < count ), иначе рискуете схватить переполнение буфера.
    {
            arrap[i] = new Distance;
            memset( arrap[i], 0, sizeof(Distance) ); //если не прочитает - значения x и y будут == 0
            inFile.read((char*)arrap[i], sizeof(Distance));
 
            if(inFile.eof())
                break;
 
            i++;
    }
    if(!inFile)
    {
        cerr << "\nReading is impossible.\n";
        return;
    }
 
    inFile.close();
}
 
int main()
{
    for( int i = 0; i < count; i++ )
    {
        arrap[i] = new Distance;
        arrap[i]->x = 5; //инициализировать заведомо известными числами
        arrap[i]->y = 8; //инициализировать заведомо известными числами
    }
 
    write();
 
    for( int i = 0; i < count; i++ )
    {
        delete [] arrap[i];
    }
 
    read();
 
    cout << "\n-- Read data: ---------------------\n";
 
    for( int i = 0; i < count; i++ )
    {
        cout << arrap[i]->x << ';' << arrap[i]->y;
 
        if( arrap[i]->x == 5 && arrap[i]->y == 8 )
           cout << " - OK" << endl;
        else
           cout << " - FAIL" << endl;
 
        delete [] arrap[i];
    }
}
Ваша ошибка в том, что вы проверяете ( !inFile ). inFile будет == false в том числе, если установлен eof-bit. Открыт файл, или нет, проверяют с помощью ( inFile.is_open() == true )
1
2 / 2 / 1
Регистрация: 02.11.2010
Сообщений: 78
11.02.2011, 11:59 6
Цитата Сообщение от WinstonCherchil Посмотреть сообщение
Хорошо написал. Спасибо.
присоединяюсь.
Файлы ещё не проходил, поэтому сразу сохранил себе этот пост
0
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 15:07 7
Цитата Сообщение от talis Посмотреть сообщение
Ваша ошибка в том, что вы проверяете ( !inFile ). inFile будет == false в том числе, если установлен eof-bit. Открыт файл, или нет, проверяют с помощью ( inFile.is_open() == true )
Спасибо большое! Почерпнул новой информации от Вас.
Но вот, крутил-крутил головой. В методе read(), фактически, ничего не поменялось, кроме дополнительного метода при чтении. (отдельное спасибо за него.) Почему же работает тогда? Я имею в виду, что такого поменялось, что код непосредственно чтения не изменился, но стал работать?
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.02.2011, 15:13 8
Да, собственно, ничего. Вы писали:

C++
1
2
3
4
5
6
7
8
if(!inFile)
{
    cerr << "\nНевозможно произвести чтение из файла.\n";
    _getch();
    exit(1); //это завершало программу преждевременно. Я просто вернул из функции.
               //кроме того, вторая такая проверка после цикла чтения (как и после цикла записи) избыточна
               //и не имеет смысла.
}
Старайтесь не пользоваться функцией exit(); Её часто применяют в игрушках. Знаете, когда игра вылетает без объяснений на середине сохранения, и пол-вечера игры псу под хвост? Вот это, скорее всего, оно. Когда винда прерывает игру - вы видите "Отправить отчёт - Не отправлять отчёт", а это именно игрушка вылетает. В функциях, в которых возможна ошибка - старайтесь возвращать либо bool (успешно/не успешно), либо int с кодом конкретной ошибки. Тогда вы сможете судить о том, что пошло не так, а не просто вылетать.
0
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 15:23 9
В общем я так понял, чтобы наверняка, нужно для начала вычислить (если файлу открывается уже после нового запуска программы, что обнуляет count), сколько объектов класса записано в файл. И делать цикл i<count
Иначе ничего не получается.
1
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.02.2011, 15:30 10
Да, так и нужно делать. Но не то, чтобы не получится... Понимаете, если вы например выделили память под массив из 5 int'ов - это 5 * 4 = 20 байт:

00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00

И начали их читать, но прочитали 6 int'ов:

00 00 00 40 | 00 00 80 1A | 7F FF FF FF | F0 00 0A 13 | DE AD BE EF | 00 00 40 0D

Вы вылезете за пределы массива. Компилятор вам ничего не скажет. Вы либо схватите ошибку сегментации памяти - SEGFAULT, либо затрёте какую-то информацию, которая была на месте 5'го int'а.

Поэтому нужно точно знать, сколько байт вам нужно.
1
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 16:00 11
В общем, я даже не знаю что делать.
1 - записываю три объекта в файл. Каждый объект занимает 8 байт (4 инт, 4 флоат)
2 - на выходе получаю файл размером 24 байта.
3 - при чтении, проверяю, сколько объектов записано в файл и считываю их в цикле.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Distance::read()
{
    ifstream inFile;
    inFile.open("DIST.DD", ios::in|ios::binary);
    if(!inFile)
    {cerr << "\nНевозможно открыть файл для чтения данных.\n"; return;}
    inFile.seekg(0,ios::end);
    int endpos = inFile.tellg();
    int num = endpos/sizeof(Distance);
    cout << "\nИдет чтение " << num << " записей.\n";
    for(int i=0; i<num; i++)
    {
        arrap[i] = new Distance;
        memset( arrap[i], 0, sizeof(Distance) );
        inFile.read((char*)arrap[i], sizeof(Distance));
    }
    if(!inFile)
    {cerr << "\nНевозможно произвести чтение из файла.\n"; return;}
    inFile.close();
}
Итог - "Невозможно произвести чтение из файла."
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.02.2011, 16:04 12
Ну правильно. Зачем-то после цикла считывания вы проверяете
C++
1
2
3
if(!inFile)
        {cerr << "\nНевозможно произвести чтение из файла.\n"; return;}
        inFile.close();
Во-первых, скажите зачем? Во-вторых, в конце чтения вы упираетесь в конец файла и выставляется бит eof (end-of-file). Проверка !inFile выполняется и вам выводится сообщение "Невозможно произвести чтение из файла". Уберите эту проверку вообще, она там не нужна. Лучше проверьте, что вы прочитали - скорее всего, данные будут верны.
0
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 16:10 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
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
// 12_1.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <fstream>
#include <process.h>
#include <windows.h>
using namespace std;    
 
const int MAXARR = 100;
 
 
class Distance
{
private:
    int feet;
    float inches;
    static int count;
    static Distance* arrap[];
public:
    void getdata()
    {
        cin.ignore(10,'\n');
        cout << "Введите футы: "; cin >> feet;
        cout << "Введите дюймы: "; cin >> inches;
    }
 
        void putdata()
    {
        cout << "Feets: " << feet;
        cout << "Inches: " << inches;
    }
 
    static void add();
    static void write();
    static void read();
    static void display();
};
 
int Distance::count=0;
Distance* Distance::arrap[MAXARR];
 
 
void Distance::add()
{
    arrap[count] = new Distance;
    arrap[count++]->getdata();
}
 
void Distance::write()
{
    ofstream outFile;
    outFile.open("DIST.DD", ios::trunc|ios::binary);
    if(!outFile)
    {cerr << "\nНевозможно открыть файл для записи данных.\n"; return;}
 
    for(int i=0; i<count; i++)
    {
        outFile.write((char*)(arrap[i]), sizeof(Distance));
    }
    if(!outFile)
    {cerr << "\nЗапись в файл невозможна.\n"; return;}
    outFile.close();
}
 
void Distance::read()
{
    ifstream inFile;
    inFile.open("DIST.DD", ios::in|ios::binary);
    if(!inFile)
    {cerr << "\nНевозможно открыть файл для чтения данных.\n"; return;}
    inFile.seekg(0,ios::end);
    int endpos = inFile.tellg();
    int num = endpos/sizeof(Distance);
    cout << "\nИдет чтение " << num << " записей.\n";
    for(int i=0; i<num; i++)
    {
        arrap[i] = new Distance;
        memset( arrap[i], 0, sizeof(Distance) );
        inFile.read((char*)arrap[i], sizeof(Distance));
    }
    //if(!inFile)
    //{cerr << "\nНевозможно произвести чтение из файла.\n"; return;}
    inFile.close();
}
 
void Distance::display()
{
    for(int i =0; i<count; i++)
        arrap[i]->putdata();
}
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    char choice;
    while(true)
    {
        cout << "\nЧто? a/w/r/d/x/p: ";
        cin >> choice;
        switch(choice)
        {
        case 'a':
            Distance::add(); break;
        case 'w':
            Distance::write(); break;
        case 'r':
            Distance::read(); break;
        case 'd':
            Distance::display(); break;
        case 'x':
            exit(0);
        default:
            cout << "Неверный атрибут.\n";
        }
    }
 
    _getch();
    return 0;
}
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.02.2011, 16:45 14
Зачем в class Distance ваше Distance* arrap[]; ? Вы в объекте типа Distance храните указатели на объекты типа Distance, которые хранят указатели на объекты типа Distance, которые хранят указатели на объекты типа Distance, которые хранят указатели на объекты типа Distance... Чего вы пытаетесь этим добиться?

Добавлено через 7 минут
Я бы сделал так:

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
class Distance
{
private:
        int feet;
        float inches;
public:
        void getdata()
        {
                cin.ignore(10,'\n');
                cout << "Введите футы: "; cin >> feet;
                cout << "Введите дюймы: "; cin >> inches;
        }
 
        void putdata()
        {
                cout << "Feets: " << feet;
                cout << "Inches: " << inches;
        }
 
        void setInches( float _inches ){ inches = _inches; };
        void setFeet( int _feet ){ feet = _feet ; };
 
        float getInches(){ return inches; };
        int getFeet(){ return feet; };
};
 
const int arrap_count;
Distance* arrap[ arrap_count ];
 
 
void write()
{
//...
   file.write( (char*)(arrap_count), sizeof(arrap_count) );
 
   for( int i = 0; i < arrap_count; i++ )
   {
      float inches = arrap[i]->getInches();
      int feet = arrap[i]->getFeet;
      file.write( (char*)(inches), sizeof(inches) );
      file.write( (char*)(feet), sizeof(feet) );
   }
//...
}
 
void read()
{
//...
   float inches
   int feet
   file.read( (char*)(inches), sizeof(inches) );
   file.read( (char*)(feet), sizeof(feet) );
   arrap[i]->setInches( inches );
   arrap[i]->setFeet( feet );
//...
}
Добавлено через 6 минут
А ещё лучше как-то так:

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
class Distance
{
private:
        int feet;
        float inches;
public:
        Distance( int feet, float inches ){ setFeet( feet ); setInches( inches ); };
 
        void getdata()
        {
                cin.ignore(10,'\n');
                cout << "Введите футы: "; cin >> feet;
                cout << "Введите дюймы: "; cin >> inches;
        }
 
        void putdata()
        {
                cout << "Feets: " << feet;
                cout << "Inches: " << inches;
        }
 
        void setInches( float _inches ){ inches = _inches; };
        void setFeet( int _feet ){ feet = _feet ; };
 
        float getInches(){ return inches; };
        int getFeet(){ return feet; };
};
 
list<Distance>arrap;
 
void write()
{
//...
   file.write( (char*)(arrap.size), sizeof(arrap.size) );
 
   list<Distance>::iterator it = arrap.begin();
 
   for( int i = 0; i < arrap.size; i++ )
   {
      float inches = (*it)->getInches();
      int feet = (*it)->getFeet;
      file.write( (char*)(inches), sizeof(inches) );
      file.write( (char*)(feet), sizeof(feet) );
      it++;
   }
//...
}
 
void read()
{
   
//...
   int size;
   file.read( (char*)(size), sizeof(size) );
 
   arrap.clear();
 
   for( int i = 0; i < size; i++ )
   {
      float inches;
      int feet;
 
      file.read( (char*)(inches), sizeof(inches) );
      file.read( (char*)(feet), sizeof(feet) );
 
      Distance dist ( feet, inches );
      arrap.push_back( dist );
   }
//...
}
1
23 / 20 / 3
Регистрация: 12.08.2010
Сообщений: 206
11.02.2011, 17:01 15
Спасибо.
В Ваших случаях, для меня, пока-что много пробелов.
0
0 / 0 / 0
Регистрация: 09.02.2011
Сообщений: 25
13.02.2011, 03:42  [ТС] 16
Ребят, всем большое спасибо)))))))))))))
0
13.02.2011, 03:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.02.2011, 03:42
Помогаю со студенческими работами здесь

Поиск в массиве структур по заданному полю и вывод в алфавитном порядке (файловый ввод/вывод)
Помогите с функцией void runFile() что бы с файла брал и выводил в алфавитном порядке список...

Вывод суммы в файл (файловый ввод/вывод)
Добрый день! Я пытался написать программу, которая должна вводить данные из файла №1, потом...

файловый ввод/вывод
Здравствуйте! Ест файл такого типа: 09.01.1975 0: 23-49-30.50;...

Файловый ввод/ вывод
Подскажите, пожалуйста, как добавить в программу файловый ввод и вывод? Если можно напишите...

Файловый ввод/вывод
Народ очень прощу, помогите. Нужно написать программу до завтра, а то отчислят. А я даже не знаю...

Файловый ввод вывод
написал программу в которой &quot;А&quot; движется по полю как сделать так чтоб после каждого прыжка файл...


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

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