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

c++ работа с файлом - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.90
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
26.01.2011, 03:42     c++ работа с файлом #1
Здраствуйте,в си знания - средненькие,мне предоставилась задача - нужно згенерировать файл для ипфильтра торрента,с сайта провайдера мне даётся только перечень адресов с которых трафик-бесплатный,тоесть мы имеем файлик - ip.txt в котором записаны адреса в формате -
22.55.105.30/20

Пишу консольку,вин 32,пустую.

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
#include "table.h"
void main()
{
    setlocale (LC_CTYPE, ".1251"); 
    setlocale (LC_MONETARY, ".1251"); 
    ifstream _in;
    _in.open("ip.txt",ios::_Nocreate);
    if(!_in)
        printf("Ненайден файл ip.txt");
    else 
    {
        cout<<"Файл найден,приступаем:";
        d();//дальше работаем с файлом
    }
    _in.close();
_getch();
}
 
void d()
{
    int num;//количество строк
    int col=0;//количество адресов занесенных в исходный масив
    int n=0;//колтчество знаков до значущой цыфры
    int ncol=3;//на сколько нужно добавить к индексу массива для сходства редактированого и нередактир.
    //равно трём т.к. первая точка встретится на 4-м индексе
    char buffer[20];    
    cout<<"\nоткрываем...";
    cout<<"\nВведите количество строк в файле";
    cin>>num;
    char** buf=new char*[num+1];//масив для наработки вид 0,00,0,000/00
    ifstream _in;
    _in.open("ip.txt");
    for(int i=0;!_in.eof();++i) //подсчет количества строк 
    {           
        _in.getline(buffer,21);
        cout<<'\n'<<buffer;//закоментировать
        buf[i]=buffer;
    }
    char **mas=new char* [num*2+3];//создание вертикального масива в первой ячейке 000,000,000,000 в последней 255,255,255,255
    for(int i=0;i<num;++i)
    {
        n=0;
        for(int x=0;x<20;++i)
        {
            switch(buf[i][x])
            {
            case '.':
                switch(n)//добавляем к ncol 4 потому,что следующая точка будет через 4-е индекса
                {
                case '3':buffer[ncol-3]=buf[i][x-3];buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '1':buffer[ncol-3]='0';buffer[ncol-2]='0';buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '2':buffer[ncol-3]='0';buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                }
                n=0;break;
            case '/':
                switch(n)//добавляем к ncol 4 потому,что следующая точка будет через 4-е индекса
                {
                case '3':buffer[ncol-3]=buf[i][x-3];buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '1':buffer[ncol-3]='0';buffer[ncol-2]='0';buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '2':buffer[ncol-3]='0';buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                }
                n=0;break;
            case '\0':
                switch(n)
                {
                case '3':buffer[ncol-3]=buf[i][x-3];buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '1':buffer[ncol-3]='0';buffer[ncol-2]='0';buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '2':buffer[ncol-3]='0';buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                }
                n=0;break;
            default:++n; break;
            }
            
        }
 
    }
    
    
    
 }

ошибку выбивает в свитче,но если использую иф- то ошибка тоже вылетает,насколько я понял у меня незаполняется массив?Код писал с нуля уже 6-й раз,каждый раз пробуя по разному считывать,т.к. в си множество способов.

ошибка - Unhandled exception at 0x00a11946 in ip.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.
предлагает продолжить или прервать

п.с. пользуюсь Visual Studio 2008
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.01.2011, 03:42     c++ работа с файлом
Посмотрите здесь:

работа с файлом C++
C++ Работа с файлом
C++ Работа с файлом
C++ работа с файлом
Работа с файлом C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
26.01.2011, 03:59     c++ работа с файлом #2
C++
1
char buffer[20];
это может хранить только одну строку

C++
1
buf[i]=buffer;
один буфер для всех строк, каждая новая строка будет затирать предыдующую, в конце останется только последняя

у тебя ещё путаница насчёт 0 и '0', это разные вещи, 0 - это число ноль, а '0' - это символ ноль
символ ноль равен числу, число определяется из символьной таблицы, в ASCII код нуля 48

Добавлено через 5 минут
Цитата Сообщение от sadok
Код писал с нуля уже 6-й раз
сначала нужно продумать алгоритм, это сократит количество раз в несколько раз
для алгоритма нужно поставить задачу, это сократит количество раз в несколько раз
файл не должен несколько раз открываться и эти моменты отлетают ещё при продумывании алгоритма
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
27.01.2011, 00:16  [ТС]     c++ работа с файлом #3
сначало мы в буфер копируем строку за строкой из файла и вставляем в двухмерный массив -динамический чар под названием buf .

Какая путаница с 0 ? с нуля начинается масив,поетому и исользую проходы цыклов с 0.


Алгоритм есть -

считываем с файла строку- buffer
записываем данные из buffer в массив -buf (вид строки - xxx.xxx.xxx.xxx/xxx)
преобразовываем массив цыклом с использованием счётчиков ncol,n и записываем переделанные в строку - buffer
после етого(я ещё ето в коде не зделал) заменяем i-й елемент массива buf.

тоесть мы считали и привели к виду - xxx.xxx.xxx.xxx/xxx
просто в файле могут иметь вид - x.xx.x.xx/xx и подобные

после привода к виду xxx.xxx.xxx.xxx/xxx
мы разделяем строку на две -
то что было до слеша в обдну ячейку массива mas ,а после совместо с 3-я значениями(xxx.xxx.xxx.)
и значением после слеша,запишутся в следующий елемент(ячейку)матрицы - mas.

п.с.
num-колличество строк в файле
buffer - строка для преобразования елементов
buf -массив [num+1][20]
mas-массив уже отредактированный-тоесть его записываем в файл(другой тхт файл)
имеет размерность [num*2+3][16], +3,потому что первым елементом будет 000.000.000.000 ,предпоследним -255.255.255.255 -етих 2-х нету в файле

Добавлено через 3 минуты
ещё раз поясню задачу -
в файле -

22.33.44.1/20
44.55.66.1/20


нужно записать в другой файл-

000.000.000.000-022.033.043.255
022.033.044.021-044.055.065.255
044.055.066.021-255.255.255.255

Добавлено через 1 час 31 минуту
Цитата Сообщение от accept Посмотреть сообщение
у тебя ещё путаница насчёт 0 и '0', это разные вещи, 0 - это число ноль, а '0' - это символ ноль
символ ноль равен числу, число определяется из символьной таблицы, в ASCII код нуля 48
тоесть если я присваеваю - 0,то в массив запишем 0,а если- '0' ,то запишется 48?)
я думал что чар поетому передаём 0, а разве выражение нельзя брать в кавычки?
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
27.01.2011, 04:03     c++ работа с файлом #4
Цитата Сообщение от sadok
Какая путаница с 0 ?
C
1
2
3
4
5
6
7
            switch(n)//добавляем к ncol 4 потому,что следующая точка будет через 4-е индекса
            {
                case '3':buffer[ncol-3]=buf[i][x-3];buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                case '1':buffer[ncol-3]='0';buffer[ncol-2]='0';buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
                                case '2':buffer[ncol-3]='0';buffer[ncol-2]=buf[i][x-2];buffer[ncol-1]=buf[i][x-1];ncol+=4;break;
            }
            n=0;break;
n - целое, а проверяется на содержание символа, в то время как в n ничего подобного не записывается нигде

Цитата Сообщение от sadok
Алгоритм есть -
алгоритм чего ? какой задачи ?
такой? какие-то там адреса айпи предоставляются ... нужно сгенерировать файл какой-то там ... даётся только перечень адресов

а надо так
в начале есть: файл, в нём адреса, формат адреса такой-то
нужно получить: файл, в нём адреса, удовлетворяющие условию
условие: адрес в таком-то диапазоне

когда задача поставлена, тогда и делается алгоритм

считываем с файла строку- buffer
записываем данные из buffer в массив -buf (вид строки - xxx.xxx.xxx.xxx/xxx)
это псевдокод уже
когда алгоритм составил, понятный для человека, по нему пишешь псевдокод (он сокращает время, поначалу-то можно без всего писать и переписывать, переписывать)

Добавлено через 7 минут
Цитата Сообщение от sadok
нужно записать в другой файл-
так тебе ещё надо их разворачивать ? это уже не просто выбрать, это выбрать и развернуть
две функции: одна проверяет айпи, а другая разворачивает его

Цитата Сообщение от sadok
я думал что чар поетому передаём 0, а разве выражение нельзя брать в кавычки?
такое свойственно всяким скриптовым языкам
а здесь все кавычки означают разное

0 - число
'0' - символ ноль
"0" - строка, которая содержит два символа: символ ноль '0' и символ конца строки '\0'

0 == '\0'
0 != '0'

по символу конца строки функции определяют, где остановиться
например strlen() подсчитывает длину строки, она её определяет по нуль-символу в конце, пока она не встретит нуль-символ, она будет считать
а функция printf() определяет, где закончить выводить строку
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
27.01.2011, 22:01  [ТС]     c++ работа с файлом #5
я знаю про \0


как ето n нигде не записывается?
первый свитч -

C++
1
default:++n; break;
попробуй у себя скомпилировать поймёш,ошибки нету,но насколько я понимаю,невыделяется память под массив buf

Добавлено через 41 минуту
мне бы из советов сначало,почему у меня при работе скомпилированого файла,останавливается процес и выдает ошибку?
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
28.01.2011, 05:24     c++ работа с файлом #6
Цитата Сообщение от sadok
как ето n нигде не записывается?
первый свитч -
если ты проверяешь символы в switch'е, то туда должен записываться символ, а символ туда не записывается
C
1
2
    case '3':
    case '1':
вот это вот по-твоему что ?
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
28.01.2011, 17:03  [ТС]     c++ работа с файлом #7
Цитата Сообщение от accept Посмотреть сообщение
если ты проверяешь символы в switch'е, то туда должен записываться символ, а символ туда не записывается
C
1
2
    case '3':
    case '1':
вот это вот по-твоему что ?


если количество знаков(цыфр) до знака препинания( . или /) равно 3-м,то делаем то-то...а если 2-м , то то...если 1-му,то ...

Добавлено через 22 секунды
ты скомпилируй и поймёш в чём проблема
NiRamz
209 / 209 / 16
Регистрация: 26.12.2010
Сообщений: 691
28.01.2011, 17:21     c++ работа с файлом #8
sadok он говорит вот про что,
у вас n - целое число, а в case вы проверяете символы.
C++
1
2
3
4
5
    switch(n)
    {
    case 0: ;
    case 1: ;
    }
вот про чего он вам объяснял
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
28.01.2011, 19:04  [ТС]     c++ работа с файлом #9
аааа,спс теперь понял , тоесть нельзя брать вкавычки при кейсе?
по учебнику так писалось
NiRamz
209 / 209 / 16
Регистрация: 26.12.2010
Сообщений: 691
28.01.2011, 19:07     c++ работа с файлом #10
посмотрите таблицу asii. если взять в одинарные ковычки, то компилятор думает что там символ. к примеру ноль в asii это 48. и для того что бы выбор упал на case '0': ; значение, которое передается в n должно было бы быть равное 48.
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
28.01.2011, 19:12  [ТС]     c++ работа с файлом #11
понял,ну всеровно выбивает ошибку при работе -
жолтая стрелка на свитч от buf[i][x]
и когда смотриш -
autos buf[i] пишет еррор - expression cannot be evaluated
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
29.01.2011, 09:46     c++ работа с файлом #12
у тебя там ещё ошибок куча

C++
1
switch(buf[i][x])
перед этой строкой вставь
C++
1
cout << "check" << i << endl;
чтобы узнать, когда оно выпадает

прикинь, у тебя все указатели указывают на один и тот же буфер, потому что ты делаешь buf[i]=buffer;

C++
1
_in.getline(buffer,21);
buffer имеет длину 20, какое 21 ?

зачем вообще память выделять под указатели, если на первых порах их можно сделать автоматическими в виде
C++
1
2
    char buf[500][1000];
    int num;
а уже потом, когда всё готово, переделать их на динамические (в num сохраняешь количество строк, записанных на данный момент)

C++
1
for(int i=0;!_in.eof();++i) //подсчет количества строк
зачем ? сразу загружай строки в buf, проверяй границу, чтобы в buf не загрузилось больше строк, чем он может вместить

C++
1
2
    for (i = 0; i < 500 && in.getline(buf[i], sizeof buf[0]); i++)
        ;
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
29.01.2011, 17:58  [ТС]     c++ работа с файлом #13
Цитата Сообщение от accept Посмотреть сообщение
у тебя там ещё ошибок куча
Код C++
1
switch(buf[i][x])
перед этой строкой вставь
Код C++
1
cout << "check" << i << endl;
чтобы узнать, когда оно выпадает
прикинь, у тебя все указатели указывают на один и тот же буфер, потому что ты делаешь buf[i]=buffer;
я добавил cout и после него поставил _getch(); при проходе по i последнему,где '\0'

начсёт buffer
присваиваю буферу,т.к. заполняю его так -
наподобии кода -
C++
1
2
3
4
5
6
7
8
char mas[20];
char mas2[_MAX_PATH][20];
for(int i=0;i<_MAX_PATH;++i)
{
cout<<"Введите елемент массива";
cin.getline(mas,20);
strcpy(mas2[i],mas);
}
Добавлено через 40 секунд
исправил детлайн с 21 на 20,спс незаметил

Добавлено через 2 минуты
смотри из файла максимальная длина строки- ( 19 + 1 )- концевой
мы каждую строку считываем в буффер,а потом копируем значение в массив buf
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
30.01.2011, 06:49     c++ работа с файлом #14
Цитата Сообщение от sadok
смотри из файла максимальная длина строки- ( 19 + 1 )- концевой
geltline() остановится на переводе строки, sizeof она получает для того, чтобы не вылезти за край буфера, в который она записывает, поэтому нет разницы сколько там, 1000 или 20
при этом 20 не даёт возможности для расширения, например невозможно поменять способ записи адресов в файле

C++
1
2
cin.getline(mas,20);
strcpy(mas2[i],mas);
зачем делать одно и то же два раза, если это можно записать в виде одного getline()
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
31.01.2011, 00:21  [ТС]     c++ работа с файлом #15
потому что в моём коде ето указатель на массив чара,тоесть мы должны присвоить массив

Добавлено через 9 часов 35 минут
переписал программу,на векторе состоящий из строк
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
#include "my.h"
vector <string> mas2;
vector <string> mas;
    string tmp;
int main()
{
    setlocale (LC_CTYPE, ".1251"); 
    setlocale (LC_MONETARY, ".1251"); 
    ifstream in("ip.txt");
    if(!in){
        printf("Ненайден файл ip.txt");
        return 0;}
    cout<<"Файл найден,приступаем:";
    while(getline(in,tmp,'\n')){    // считываем пока считывается 
     mas.push_back(tmp);// запихиваем в vector
      }
    /*for(int i=0;i<mas.size();++i)
    cout<<'\n'<<(mas)[i];*/
    in.close();
    dmain();
    _getch();
}
void dmain()
{
    int t=dedit();//преобразовываем массив из 22.134.2.2/45  в 022.134.002.002/045
    if(!(t==-1) && !(t==0)) cout<<"\nошибка в "<<t<<"-й строке";
    dmakemas();//разделяем по  '/' на два елемента массива
    dwrite();//записываем данные в файл
}
int dedit()
{
    int num=0;//количество строк
    int n=0;//количество знаков до значущой цыфры
    int ncol;//на сколько нужно добавить к индексу массива для сходства редактированого и нередактир.
    //равно трём т.к. первая точка встретится на 4-м индексе    
    for(int i=0;i<mas.size();++i)
    {
        ncol=3;
        n=0;
        num=0;
        for(int x=0;x<=mas[i].length();x++)
        {
            if(n>3) return i+1;//проверка на количество знаком между знаками препинания 
            switch(mas[i][x])
            {
            case '.':
                switch(n)//добавляем к ncol 4 потому,что следующая точка будет через 4-е индекса
                {
                case 3:tmp[ncol-3]=mas[i][x-3];tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 1:tmp[ncol-3]='0';tmp[ncol-2]='0';tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 2:tmp[ncol-3]='0';tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                }
                ncol+=4;n=0;num++;break;
            case '/':
                switch(n)//добавляем к ncol 4 потому,что следующая точка будет через 4-е индекса
                {
                case 3:tmp[ncol-3]=mas[i][x-3];tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 1:tmp[ncol-3]='0';tmp[ncol-2]='0';tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 2:tmp[ncol-3]='0';tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                }
                ncol+=4;n=0;num++;break;
            case '\n':
                switch(n)
                {
                case 3:tmp[ncol-3]=mas[i][x-3];tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 1:tmp[ncol-3]='0';tmp[ncol-2]='0';tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                case 2:tmp[ncol-3]='0';tmp[ncol-2]=mas[i][x-2];tmp[ncol-1]=mas[i][x-1];tmp[ncol]=mas[i][x];break;
                }
                num++;break;
            default:++n;break;
            }   
        }
        if(!(num==4)) return i+1;//проверяем строку на 4-е знака препинания
        cout<<'\n'<<tmp;
    }
    return 0;
 }
 
void dmakemas()
{
}
void dwrite()
{
}
но вот проблема появилась с выполнением если между знаками . и /,поставить по одному елементу ,то выбьет ошибку стринг вышел из диапазона,да и проблема с строками - с 2-й строки после знака / присваивается и первой(((( нужно компилировать,иначе не поймёте
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
31.01.2011, 00:59  [ТС]     c++ работа с файлом #16
вот,но ето только насчёт последних чисел,а насчёт количества нужно компилировать,там если до знака / меньше определённого количества,то результаты вывода последней строки-меняются. по чему-то влияние на вывод идёт по последней строчке
Миниатюры
c++ работа с файлом  
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
31.01.2011, 01:02  [ТС]     c++ работа с файлом #17
вот несколько примеров
Миниатюры
c++ работа с файлом   c++ работа с файлом  
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
31.01.2011, 01:03  [ТС]     c++ работа с файлом #18
причём на листе бумаги всё идёт идеально((( тоесть расписываю каждый проход цикла.
Может проблема в подсчёте '\n' в свитче, пробовал и '\0' -только его вообще невидет,тоесть выбивает ошибку - num<4,тоесть равен 3-м
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
31.01.2011, 06:41     c++ работа с файлом #19
Цитата Сообщение от sadok
стринг вышел из диапазона
C++
1
for(int x=0;x<=mas[i].length();x++)
x <

C++
1
case '\n':
это когда такой случай наступит ?
getline() не сохраняет их

C++
1
case '/':
подразумевает, что там три символа после слеша

с числами лучше работать, когда они являются числами
то есть эти числа считываются прямо в int переменные, чтобы потом можно было их сравнивать
есть stringstream - такая штука, с помощью которой можно строку превратить в поток и считывать из неё в переменные
C++
1
2
3
4
5
6
7
8
    int o[4], m;
    char sep[4];
 
    ss >> o[0] >> sep[0]
       >> o[1] >> sep[1]
       >> o[2] >> sep[2]
       >> o[3] >> sep[3]
       >> m;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.01.2011, 17:26     c++ работа с файлом
Еще ссылки по теме:

C++ C++. Работа с файлом
Работа с файлом C++
Работа с файлом C++

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

Или воспользуйтесь поиском по форуму:
sadok
14 / 14 / 0
Регистрация: 26.01.2011
Сообщений: 64
31.01.2011, 17:26  [ТС]     c++ работа с файлом #20
непонял,можно пример,что-то неврубаюсь - потом стиргстим только сейчас буду учить =))) я вектортолько позавчера выучил=))
Yandex
Объявления
31.01.2011, 17:26     c++ работа с файлом
Ответ Создать тему
Опции темы

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