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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
#1

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

16.10.2011, 08:59. Просмотров 1178. Ответов 22
Метки нет (Все метки)

Нахрена? я изучал и читал и не нашел плюсов. смотрите:
Я создал поток, подключил в него буфером строку для парсинга:
Код
    -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++
Доброго врмени суток, помогите найти ошибку!!! /после выхода из этой функции func2 нужные мне значения counter, index обнуляються , в...

Что такое потоки ввода, потоки вывода? - C++
Здарова всем! Не так давно уже прогаю на С++ и все НИКАК не могу понять, что такое потоки ввода, потоки вывода..! вот допустим...

VC, потоки. - C++
Вот что я написал: #include <stdio.h> #include <stdlib.h> #include <afxwin.h> UINT myproc1 (LPVOID pParam) { return 0; } ...

Потоки - C++
Я нашел в интернете отличную статью про потоки и многопоточность и на её основе написал следующую программу: #include "stdafx.h" ...

Потоки - C++
Я создаю поток так: CreateThread(NULL, 0, MyThread, (LPVOID)&param, 0, NULL); Но мне нужно обработать 100 раз функцию MyThread. 100...

потоки - C++
как с помошью потоков считать из файла два числа K и N: ifstream input("input.txt",ifstream::binary); int K,N;

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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
3034 / 2355 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
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
3034 / 2355 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
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
3034 / 2355 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
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
791 / 543 / 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
3034 / 2355 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
16.10.2011, 11:24 #12
Цитата Сообщение от CEBEP Посмотреть сообщение
Крупными порциями читать чтобы добиться эффективной работы жесткого диска
Вообще при открытии файл буферизуется, и если позволяет размер, полностью загружается в оперативную память, дальнейшая работа идет в памяти.

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

Добавлено через 2 минуты
13 - символ перевода каретки в начало строки, 10 - банальный '\n'
Это - в винде. В никсах как раз только \n
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
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 Посмотреть сообщение
файл буферизуется
вау! мб тогда вообще не перетягивать его в строковый поток а нормально будет парсить сразу из файлового?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2011, 11:34
Привет! Вот еще темы с ответами:

Потоки - C++
Есть 2 потока: main_thread и thread Как из main_thread завершить thread?

Потоки с++11 - C++
Подскажите, где почитать про потоки в новом стандарте плюсов

Потоки - C++
Есть некоторая консольная программа. Необходимо обернуть ее в гуи, то есть самого консольного окна быть не должно. Как я понял это проще...

Потоки - C++
Задание: 1.Отображение списка запущенных потоков. 2.Создание нового потока по запросу пользователя.(это у меня сделано и работает) ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
16.10.2011, 11:34
Ответ Создать тему
Опции темы

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