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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
#1

Считывание текстового файла - C++

10.07.2013, 18:18. Просмотров 780. Ответов 11
Метки нет (Все метки)

Помогите, пожалуйста, разобраться.
При считывании текстового файла, последние несколько символов считываются 2 раза, т.е., если исходный файл был:
"Hi. How are you?", то компилятор считает его примерно так: "Hi. How are you?re you?". Почему так происходит?
В кат скидываю код
Кликните здесь для просмотра всего текста
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
#include <cstdio>
 
static const int ARRAY_SIZE_CONST = 100;
 
static const char COMMENT_SYMBOLS[ARRAY_SIZE_CONST] = {'#', '['};
static const int COMMENT_SYMBOLS_LENGTH = 2;
 
struct String
{
    char data[ARRAY_SIZE_CONST];
    int length;
};
 
void parseLine_ (FILE* file, String& string);
void parseBlock_ (FILE* file, const int nStrings, String* string);
void parseSkipString_ (FILE* file);
void parseSkipComment_ (FILE* file, const char* commentSymbols, const int commentSymbolsLength);
 
// mode 0 : reads all strings in parameters[0]
// mode 1 : reads only parameters
// mode 2 : reads at first static parameters, then all other parameters
void parseFile (const char* fileName, const int mode,
                const char* commentSymbols, const int commentSymbolsLength,
                String* staticParameters, const int staticParametersLength, 
                String** parameters, const int parametersLength);
 
int main()
{
    String **str = new String*[32];
        
    for(int i = 0; i < 32; i++)
        str[i] = new String[32];
 
    String strstat[ARRAY_SIZE_CONST];
 
    parseFile ("d:\\test.txt", 1, COMMENT_SYMBOLS, COMMENT_SYMBOLS_LENGTH, strstat, 1, str, 2);
 
    getchar ();
 
    return 0;
}
 
void parseLine_ (FILE* file, String& string)
{
    int i;
 
    i = 0;
 
    while ((string.data[i++] = fgetc (file)) != '\n')
        ;
 
    string.length = i - 1;
 
    return
        ;
}
 
void parseBlock_ (FILE* file, const int nStrings, String* string)
{
    int i;
 
    for (i = 0; i < nStrings; ++i)
    {
        while (fgetc (file) != '=')
            ;
 
        fgetc (file);
 
        parseLine_ (file, string[i]);
    }
 
    return
        ;
}
 
void parseSkipString_ (FILE* file)
{
    while (fgetc (file) != '\n')
        ;
 
    return
        ;
}
 
void parseSkipComment_ (FILE* file, const char* commentSymbols, const int commentSymbolsLength)
{
    int i, flag;
    char temp;
 
    do
    {
        flag = 0;
 
        temp = fgetc (file);
 
        if (temp == '\n')
            flag = 1;
        else
            for (i = 0; i < commentSymbolsLength; ++i)
                if (temp == commentSymbols[i])
                {
                    flag = 1;
                    parseSkipString_ (file);
                    break;      
                }
    }
    while (flag);
}
 
void parseFile (const char* fileName, const int mode, 
                const char* commentSymbols, const int commentSymbolsLength,
                String* staticParameters, const int staticParametersLength, 
                String** parameters, const int parametersLength)
{
    int i;
    FILE* file;
 
    file = fopen (fileName, "rt");
 
    i = 0;
 
    switch (mode)
    {
    case 0 :
        while (!feof (file))
        {
            parseSkipComment_ (file, commentSymbols, commentSymbolsLength);
 
            parseLine_ (file, parameters[0][i++]);
        }
 
        break;
 
    case 1 :
        while (!feof (file))
        {
            parseSkipComment_ (file, commentSymbols, commentSymbolsLength);
 
            parseBlock_ (file, parametersLength, parameters[i++]);
        }
 
        break;
 
    case 2 :
        parseSkipComment_ (file, commentSymbols, commentSymbolsLength);
 
        parseBlock_ (file, staticParametersLength, staticParameters);
 
        while (!feof (file))
        {
            parseSkipComment_ (file, commentSymbols, commentSymbolsLength);
 
            parseBlock_ (file, parametersLength, parameters[i++]);
        }
 
        break;
 
    // case 2, 3, ...
 
    default :
        // statements
        break;
    }
    
    fclose (file);
 
    return
        ;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.07.2013, 18:35     Считывание текстового файла #2
Дайте рабочий пример текста. У вас там цикл есть:
C++
1
while (fgetc (file) != '=');
из которого нет выхода, пока не считан '='. В тексте, из первого поста, такого символа нет.
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
10.07.2013, 19:14  [ТС]     Считывание текстового файла #3
csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.07.2013, 21:33     Считывание текстового файла #4
У вас код работает? Судя по первому посту только неправильно считывает? Сейчас запустил с первым файлом из архива - исключение, нарушение прав при записи. У вас тоже так? Или у вас какой-то другой файл?
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
10.07.2013, 23:37  [ТС]     Считывание текстового файла #5
нарушение прав при записи.
Это скорее всего из-за того, что массив маленький (строка 29).
Попробуйте создать текстовый файлик и написать там:
Кликните здесь для просмотра всего текста
# comment1
# comment2

[comment3]

block1 = data1
block2 = data2
block3 = data3
block4 = data4

И запустить процедуру с параметрами
C
1
parseFile ("path//text.txt", 1, COMMENT_SYMBOLS, COMMENT_SYMBOLS_LENGTH, strstat, 0, str, 2);
и посмотрите (в дебаг режиме), правильно ли считывает она файл. По идее, она должна считать data1, data2 в первый массив и data3, data4 во второй и на этом завершиться.

Моя задача -- написать парсер, который будет считывать все строки после знака "=", избегая строки, начинающиеся на "#" и "[".
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.07.2013, 23:55     Считывание текстового файла #6
Цитата Сообщение от vlad_light Посмотреть сообщение
Это скорее всего из-за того, что массив маленький (строка 29).
Массив там вполне достаточный (32 массива, по 32 объекта). Код кривой, и кривизны в нём немеренно.
Цитата Сообщение от vlad_light Посмотреть сообщение
Моя задача -- написать парсер, который будет считывать все строки после знака "=", избегая строки, начинающиеся на "#" и "[".
И сколько таких строк предполагается в файле?
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
11.07.2013, 00:21  [ТС]     Считывание текстового файла #7
Я не против полностью переписать код, только подскажите как.
В зип архиве, который я скидывал изначально, есть текстовые файлы следующей структуры:
# комментарии
[комментарии]

счётчик = 0
Тип1 = значение1
Тип2 = значение2

счётчик = 1
Тип1 = значение 3
Тип2 = значение 4
и т.д.
Мне нужно эти данные внести в двумерный массив: 1-ая координата отвечает за номер блока, 2-ая -- за номер строки.
Буду весьма признателен, если поможете мне в этом! Заранее спасибо!

Не по теме:

Кстати, было бы вообще шикарно, если бы Вы указали на ошибки ("кривизну") в коде, чтоб я не повторял их в дальнейшем.


И сколько таких строк предполагается в файле?
Не более 1500 строк
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.07.2013, 00:54     Считывание текстового файла #8
В каждом блоке по пять строк со знаком '=' ? Это значение фиксированное? В самом большом файле, из архива, 512 блоков (по 5 строк). Я так понимаю, это максимальное количество блоков? Там есть [ENCRYPT] и [DECRYPT], после каждого из них, COUNT начинается с 0. С этим как? В массив все блоки подряд записывать?

Добавлено через 3 минуты
И главное... С++ или С? Если С++, то string? STL?
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
11.07.2013, 01:28  [ТС]     Считывание текстового файла #9
В каждом блоке по пять строк со знаком '=' ?
Нет, разное кол-во строк (от 2 до 6). Причём, есть такие файлики, где нужно считать первые пару строк отдельно.
Это значение фиксированное?
Нет
Я так понимаю, это максимальное количество блоков?
Скорее всего
Там есть [ENCRYPT] и [DECRYPT], после каждого из них, COUNT начинается с 0. С этим как?
Слова [ENCRYPT] и [DECRYPT] тупо пропускать и считывать всё подряд. Строку COUNT считывать как и все остальные.
В массив все блоки подряд записывать?
Да
И главное... С++ или С?
С
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.07.2013, 01:42     Считывание текстового файла #10
Цитата Сообщение от vlad_light Посмотреть сообщение
Нет, разное кол-во строк (от 2 до 6). Причём, есть такие файлики, где нужно считать первые пару строк отдельно.
Имена таких файлов в архиве? Где не 5 строк.
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
11.07.2013, 01:45  [ТС]     Считывание текстового файла #11
Вот сайтец http://http://csrc.nist.gov/groups/STM/cavp/, нужно прогнать все тесты.
Имена таких файлов в архиве? Где не 5 строк.
Там при тестировании RSA задаются сначала базовые параметры, а потом куча сообщений и соответствующие шифртексты. Причём, базовые параметры в одном экземпляре, а plaintext'ов и ciphertext'ов дофига.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2013, 10:55     Считывание текстового файла
Еще ссылки по теме:

Считывание данных из текстового файла в структуру C++
C++ Считывание из текстового файла значения int
Считывание текстового файла C++
C++ Считывание строк из текстового файла
Считывание двумерного массива из текстового файла C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.07.2013, 10:55     Считывание текстового файла #12
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
#include <stdlib.h>
#include <stdio.h>
 
int main()
{
   const int N = 3000;
   const int M = 255;
   
   char str[N][M];
   char filename[30] = "OFBVarKey256.rsp";
   
   FILE *fin = fopen(filename, "r");
   if (!fin) printf("\nError!\n");
   else
   {
        int n = 0;
        char temp[255];
        while (!feof(fin))
        {
            char ch;
            ch = fgetc(fin);
            if (ch == '\n') ch = fgetc(fin);
            if (feof(fin)) break;
            if (ch == '#' || ch == '[') fgets(temp, M, fin);
            else
            {
                while (fgetc(fin) != '=');
                fgetc(fin);
                fgets(str[n], M, fin);
                ++n;
                if (n == N) break;
            }
       }
      
       for (int i = 0; i < n; ++i)
            printf("%s", str[i]);
 
       printf("\nn = %d\n", n);
       
       if (N == n && !feof(fin)) printf("\nThe array size is too small!\n");
       else printf("\nSuccessful!\n");
       fclose(fin);
   }
    
    printf("\n\nExit!");
    getchar ();
 
    return 0;
}
Yandex
Объявления
11.07.2013, 10:55     Считывание текстового файла
Ответ Создать тему
Опции темы

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