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

Проклятые потоки. - C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 08:59     Проклятые потоки. #1
Нахрена? я изучал и читал и не нашел плюсов. смотрите:
Я создал поток, подключил в него буфером строку для парсинга:
Код
    -1
   151
Scan3.svd

PSV Version 8.7.2.2
06-Oct-11 18:00:49  
None      None      
PolyUFFExport 2.0.1.0 - Compatible to LMS
10-Oct-11 18:56:20 
    -1
" -1" - строка которой начинается и заканчивается блок, 151 - константа определяющая тип блока. Мне надо считать строки 3, 5, 6, 8 и 9 в соответствующие std::string. И ещё сделать проверочку. Пускай, самую грубую. Скажем, проверить, начинается ли мой блок с -1 и известен ли мне тип 151.
-1 как число интерпретировать нельзя, так как стандарт файла предусматривает ранение целых чисел в текстовом виде и -1 может оказаться по причинам не связанным с пометкой начала блока. Следовательно, я обязан проверить всю строку. т. е.
C++
1
2
std::getline(stream, buf);
if(buf != std::string("    -1")) { /*Генерация ошибки*/ }
Но, в буфере не содержится строка равная " -1", там содержится она же но с ещё одним символом в конце. Символ имеет числовой эквивалент 13 и не является '\n', что ещё можно было бы понять. Т. е. в конструктор я строку равную получаемой передать не могу. Так же, не могу оптимизировать сравнение приготовив
C++
1
const static std::string rightBlockSign("    -1");
так как я и инициализировать строку тоже не могу нормально. Изуверства типа
C++
1
2
static std::string rightBlockSign("    -1 ");
rightBlockSign[6] = 13;
тоже не помогают.
Думаете это конец бредятины? Ошибаетесь. Дальше больше:
Пуд соли съеден каждым хомячком желающим считать строку до '\n' а не до первого пробела/табуляции/символа новой строки. Мой блок имеет пустую четвёртую строку. Мне её надо пропустить а следующую считать в переменную PSVVersion. Как? std::getline() не передвинит бегунок если строка пуста. >> считает следующее слово, то есть "PSV", и курсор опять окажется не там где надо.
Друзья мои, я на грани того чтобы вернутся в девяностые и писать всё в стиле char*, помогите, объясните как выйти из ситуации!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.10.2011, 08:59     Проклятые потоки.
Посмотрите здесь:

Потоки с++ C++
потоки.. C++
потоки C++
Потоки C++
Потоки C++
Потоки C++
потоки с++ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
greeezz
272 / 165 / 4
Регистрация: 10.07.2011
Сообщений: 441
16.10.2011, 09:40     Проклятые потоки. #2
Цитата Сообщение от CEBEP Посмотреть сообщение
Как? std::getline() не передвинит бегунок если строка пуста. >> считает следующее слово, то есть "PSV", и курсор опять окажется не там где надо.
Вами сказанное наводит на мысль что в вашем файле ( или буфере) от куда вы осуществляете чтение есть разграничительные символы которые вам мешают работать.
функция getline(str, myStr) изымает все из str и помещает в myStr до того момента пока не найден символ разграничения, например конец строки. Она не останавливается на пробеле или табуляции. В документации также сказано что остановка чтения из строки происходит при достижении конца файла или возникновения ошибки.

попробуйте например с функцией cin.get() пройти по всему тексту и выявить все символы которые действительно присутствуют. cin.get() читает все символы включая пустой.
Заранее прошу прощения если данное сообщение вам никак не помогло.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 10:03  [ТС]     Проклятые потоки. #3
Да, это не плохая мысль. Там действительно каждый конец строки представлен в виде двух байт 13 и 10... На сколько я знаю, так метят конец строки *NIX системы... и чего? Стандартная библиотека на это болт клала?

Добавлено через 2 минуты
13 - символ перевода каретки в начало строки, 10 - банальный '\n'
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
16.10.2011, 10:29     Проклятые потоки. #4
Вполне возможно это кривая реализация getline. Что за компилятор и ОС?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 10:31  [ТС]     Проклятые потоки. #5
всему виной моя сраная visual studio 2010?
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
16.10.2011, 10:38     Проклятые потоки. #6

Не по теме:

И на старуху бывает проруха


А если без шуток, то в каком режиме открыт файл, в текстовом или в бинарном?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 10:50  [ТС]     Проклятые потоки. #7
В бинарном и это тоже связано с этим символом 13... если открывать как текстовый то лишний символ действительно удаляется при считывании файла, другой вопрос что место в строке под него уже выделится так как
C++
1
2
3
        file.seekg( 0, std::ios::end );
        unsigned fSize = static_cast<unsigned>(file.tellg());
        file.seekg( 0, std::ios::beg );
не будет учитывать удаление лишнего символа, а в файле 98 тысяч строк, что преступно не учитывать.

Добавлено через 1 минуту
т. е. я конечно могу просто запустить алгоритм удаления всех байтов со значением 13 но это же костыль...
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
16.10.2011, 10:58     Проклятые потоки. #8
А зачем считывать весь файл целиком?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 11:10  [ТС]     Проклятые потоки. #9
а какая разница целиком или не целиком... Крупными порциями читать чтобы добиться эффективной работы жесткого диска а если так, нужно знать объём файла...

Добавлено через 2 минуты
я пытался считать файл с помощью потоков, но ничего не вышло.
C++
1
std::cout << fileStream.rdbuf()
работает а
C++
1
std::ostringstream(bufer) << fileStream.rdbuf()
ни к чему не приводит.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.10.2011, 11:15     Проклятые потоки. #10
CEBEP, прикрепите, пожалуйста, копию участка файла, который вы пытаетесь считать, со всем "левыми" тринадцатыми и прочими символами.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 11:20  [ТС]     Проклятые потоки. #11
http://rk5.bmstu.ru/share/uvnInfo/Scan.unv вот файл.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
16.10.2011, 11:24     Проклятые потоки. #12
Цитата Сообщение от CEBEP Посмотреть сообщение
Крупными порциями читать чтобы добиться эффективной работы жесткого диска
Вообще при открытии файл буферизуется, и если позволяет размер, полностью загружается в оперативную память, дальнейшая работа идет в памяти.

Цитата Сообщение от CEBEP Посмотреть сообщение
я пытался считать файл с помощью потоков, но ничего не вышло.
C++
1
2
3
stringstream str;
str << file.rdbuf();
cout << str.rdbuf();
ValeryLaptev
Эксперт С++
1012 / 791 / 46
Регистрация: 30.04.2011
Сообщений: 1,600
16.10.2011, 11:28     Проклятые потоки. #13
Цитата Сообщение от CEBEP Посмотреть сообщение
Да, это не плохая мысль. Там действительно каждый конец строки представлен в виде двух байт 13 и 10... На сколько я знаю, так метят конец строки *NIX системы... и чего? Стандартная библиотека на это болт клала?

Добавлено через 2 минуты
13 - символ перевода каретки в начало строки, 10 - банальный '\n'
Это - в винде. В никсах как раз только \n
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
16.10.2011, 11:33     Проклятые потоки. #14
Короче, так, судя по всему кривая getline ()

Вот я специально набросал код, там строки читаются, и первая строка -1 с помощью getline читается корректно. В неё действительно 6 знаков, как и в файле. 4 пробела, потом '-' потом 1, и никакой 13 и 10-ки
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
#include <vector>
#include <iostream>
#include <string>
#include <fstream>
 
std::vector<std::string> readFile(std::ifstream& ifs)
{
        std::string str;
        std::vector<std::string> vec;
        while(std::getline(ifs, str))
                vec.push_back(str);
        return vec;
}
 
int main()
{
        std::string str= "list.txt";
        std::ifstream ifs(str.c_str());
        if(!ifs)
        {
                std::cerr<<"Error with open file "<< str <<'\n';
                return 1;
        }
        std::vector<std::string> vec=readFile(ifs);
        for(size_t i=0; i<vec.size(); ++i)
        {
 
                std::cout<<vec[i]<<'\n';
                if (!i)
                 printf ("vec[i].size()= %d\n",vec[i].size());
 
        }
        getchar ();  
        return 0;
}

А так чувак во многом прав, я тоже психовал, не наблюдая нормального перенаправления текстового файла в строку! Это надо же нормально не реализовать простой оператор перенаправления:

C++
1
myfstream>> str
, эта херь споткнётся о первый же символ 13
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
В общем, я сделал так, написал свой класс, который реализует данную конструкцию. Результат- строка-копия текстового файла, но без 13 (10-ки остались, но они корректны)
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
//НУ короче такой вот класс служит единственно для того, чобы считать текстовый файл в 
//строку. Штатный оперетор перенаправления глючит, то есть
 
//string str;
//ifstrem f ("fail.txt");
//f>> str;
//По этому коду в str будет всё, что угодно только не заявдленное. ПРоисходит это потому
//что файловый поток спотыкается о первый непечатаемый символ. Это, кажись, перевод
//каретки на другую строку 
 
 
//                    Ф У Н К Ц И И
//Публичная функция перенаправления оператора (дрружественая) >>
//Конструктор (один принимает просто имя файла и всё)
 
//Использовать просто
//string str_0, str_1,str_2;
//myifstrem f ("ima_faila.txt");
//f>> str_0>> str_1;
//f>> str_2;
//Закрывать ничё не надо, по завершении оператора перенаправления f закроется сам
 
//Этот файл засунут в два места: в инклуды и в папку 
//мои_классы\мой_файловый_поток_myifstream
 
#ifndef MYIFSTREAM_H
#define MYIFSTREAM_H
 
#include <windows.h>
#include <iostream>
#include <fstream>
using namespace std;
 
class myifstream {
 
///+++++++++++++++++++++++++++++++++++
 private:
 
 
  char* ima_faila;
 
  ifstream f;
  long int Razmer_Faila;
 
  //функции пошли
  long int fRazmer_Faila (char* ima_faila);
 
///+++++++++++++++++++++++++++++++++++
 public:
 
  //конструкторы
  myifstream (char* p) {ima_faila= p;};
 
  friend myifstream & operator>> (myifstream & g, string& str); 
};
 
//+++++++++       определения функций     +++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
myifstream& operator>> (myifstream & g, string& str) {
 
 char temp_1, temp_2;
 
  
  //пытаемся открыть. Обязательно в бинарном режиме!
  g.f.open(g.ima_faila, ios::binary);
  if (!(g.f)) {
   cout<< "файл "<<g.ima_faila<<"  на чтение не открыт\n";
   return g;
  }
  //Устанавливаем соответтсвующий флаг
 
 //Так, размер файла ищем. КАждый раз по новой надо искать, ибо он может меняться
 g.Razmer_Faila= g.fRazmer_Faila (g.ima_faila);
 
  
 
 //Погнали считывать в строку
 //Тут есть одна фишка
 //при таком вот перегоне
 //fstream<< str
 //все символы, которые 0x0a преобразуются в 0x0d 0x0a
 //вывод:
 //Если в строке встретится 0x0d 0x0a, то 0x0d убираем          
 int i= 0;
 
 
 for (int i= 0; i< g.Razmer_Faila; i++ ) {
  temp_1= g.f.get();
  if (temp_1== 13) {
   temp_2= g.f.get();
   if (temp_2== 10) {
    str+= temp_2;
    i++;
   }
   else {
    str+= temp_1;
    str+= temp_2;
    i++;
   }
  } 
  else
   str+= temp_1;
 }
 g.f.close();
 return g;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
 
//+++++++++++++++А эта функция находит размер файла++++++++++++
long int myifstream::fRazmer_Faila (char* ima_faila) {
 HANDLE hFile;
 long int temp;
 hFile = CreateFile(ima_faila,0,FILE_SHARE_READ,NULL,OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,NULL);
 if (hFile== INVALID_HANDLE_VALUE) {
  cout<< "ничего не выйдет ибо не удаётся найти размер файла"<< endl;
  return EOF;
 }
 else {
  temp= (long int)GetFileSize(hFile, 0);
  CloseHandle (hFile);
  return temp; 
 }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
 
 
#endif
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 11:34  [ТС]     Проклятые потоки. #15
Цитата Сообщение от kazak Посмотреть сообщение
файл буферизуется
вау! мб тогда вообще не перетягивать его в строковый поток а нормально будет парсить сразу из файлового?
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
16.10.2011, 11:39     Проклятые потоки. #16
Цитата Сообщение от kravam Посмотреть сообщение
Короче, так, судя по всему кривая getline ()
С этим уже разобрались, строковые функции не для бинарного режима.

Цитата Сообщение от CEBEP Посмотреть сообщение
вау! мб тогда вообще не перетягивать его в строковый поток а нормально будет парсить сразу из файлового?
дополнительный поток не нужен
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
16.10.2011, 11:40     Проклятые потоки. #17
Цитата Сообщение от CEBEP Посмотреть сообщение
В бинарном
так если файл в бинаром режиме открыт, понятно дело, что не будет строки " -1",а будет " -11310"

Этот файл надо именно в текстовом режиме открывать и вручную обрабатывать.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 11:41  [ТС]     Проклятые потоки. #18
Цитата Сообщение от kravam Посмотреть сообщение
я сделал так
видал уже такое... Этот подход ничем не отличается от циклов по удалению лишних символов и прочего... и вообще, не лучше, чем FILE f* = fopen....
Какой-то чувак вообще накатал такой класс, который работает с long long а не с long, чтобы по надёжнее но у него не получилось кроссплатформенно и код получился такой здоровенный что вчитываться я не стал...
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
16.10.2011, 11:43     Проклятые потоки. #19
...машина пробелы убирает перед единицей

Добавлено через 1 минуту
CEBEP, а как надо-то?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2011, 11:47     Проклятые потоки.
Еще ссылки по теме:

Потоки C++
C++ потоки
C++ Проклятые функции
C++ Что такое потоки ввода, потоки вывода?
Потоки C++

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

Или воспользуйтесь поиском по форуму:
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
16.10.2011, 11:47  [ТС]     Проклятые потоки. #20
Цитата Сообщение от kravam Посмотреть сообщение
Этот файл надо именно в текстовом режиме открывать
Выше я пояснял почему я раньше выбрал открытие в виде бинарного. При открытии файла как текстового измерение размера файла не изменяет и строка выделяется больше чем нужно, что лишает смысла весь разговор ибо этот проект я намерен выполнить кристально чисто, безо всяких костылей и кодов на Cи, чистый с++

Добавлено через 1 минуту
Цитата Сообщение от kazak Посмотреть сообщение
дополнительный поток не нужен
Я напишу всё и буду тестировать производительность... отписать о результатах?
Yandex
Объявления
16.10.2011, 11:47     Проклятые потоки.
Ответ Создать тему
Опции темы

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