bool isWhitespace(const string& str)
{
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}
Обнаружить пустую строку (или продолжение к закрытой теме :))
http://forum.codenet.ru/showthread.php?t=29001 и закрыли ее :((((( а у меня тут сложность возникла....
Green, долго думал почему что-то не то получается, в итоге случайно обнаружил что вот эта конструкция:
"не чувствует" пустую строку. То есть обработка данных начинается не после прохода каждой группы, а только по достижении конца файла, что не правильно... Подскажите пожалуйста, как правильно записать пустую строку чтобы ее можно было обнаружить?
Я уже пробовал и так " \n" и так "\n" и сяк " \0".... В общем как только не пробовал, а не "ловится" эта пустая строка....
PS. И так тоже пробовал:
out << endl;
... не проходит....
Ну вот, наговорили кучу разговоров в моей теме
Green, долго думал почему что-то не то получается, в итоге случайно обнаружил что вот эта конструкция:
Код:
"не чувствует" пустую строку. То есть обработка данных начинается не после прохода каждой группы, а только по достижении конца файла, что не правильно... Подскажите пожалуйста, как правильно записать пустую строку чтобы ее можно было обнаружить?
Я уже пробовал и так " \n" и так "\n" и сяк " \0".... В общем как только не пробовал, а не "ловится" эта пустая строка....
PS. И так тоже пробовал:
out << endl;
... не проходит....
Данная функция у меня отлично отлавливает и пустую строку и строку с пробельными символами.
Что значит "записать пустую стоку"?
У тебя есть код, который формирует файл?
Ты проверял зрительно, действительно ли файл вормируется правильно?
Какая строка попадает в приведенную функцию, вместо пустой? Какие в ней символы?
Хм... файл я проверял, там действительно визуально все как надо. В пустой строке записывается пробел, потом ничего. Завтра буду за «нужным» компьютером, найду кусочек кода который формирует файл. Странно все это...
Выложи файл
Код:
ofstream out("contours.txt");
do {
//---
какие-то действия
//---
for (int i = 0; i < VecSize; i++)
{
out << ((A).x) << '\t' << ((A).y) << endl;
}
out << endl;
}while (какое-то условие)
do {
//---
какие-то действия
//---
for (int i = 0; i < VecSize; i++)
{
out << ((A).x) << '\t' << ((A).y) << endl;
}
out << endl;
}while (какое-то условие)
Я думаю, не нужно тут углубляться в то что такое (A).x и (A).y, скажем так -- это целые числа, координаты пикселей. (если чуть подробнее то А - это вектор, компонентами которого являются структуры -- но это сейчас не важно.)
Таким образом, с помощью цикла for записывается группа чисел, после нее при помощи out << endl; вставляется пустая строка. Затем опять проделываются какие-то вычисления (обозначены как "какие-то действия"), и снова записываем полученную группу и пустую строчку вслед за ней.
В итоге получаем вот такой текстовый файл (скопировал реальный):
Код:
20 21
21 20
22 20
23 20
24 20
25 20
26 21
26 22
26 23
26 24
26 25
25 26
24 26
23 26
22 26
21 26
20 25
20 24
20 23
20 22
21 22
21 21
20 63
21 62
22 62
23 62
24 62
25 62
26 63
26 64
26 65
26 66
26 67
25 68
24 68
23 68
22 68
21 68
20 67
20 66
20 65
20 64
21 64
21 63
20 106
21 105
22 105
23 105
24 105
25 105
26 106
26 107
26 108
26 109
26 110
25 111
24 111
23 111
22 111
21 111
20 110
20 109
20 108
20 107
21 107
21 106
20 149
21 148
22 148
23 148
24 148
25 148
26 149
26 150
26 151
26 152
26 153
25 154
24 154
23 154
22 154
21 154
20 153
20 152
20 151
20 150
21 150
21 149
21 20
22 20
23 20
24 20
25 20
26 21
26 22
26 23
26 24
26 25
25 26
24 26
23 26
22 26
21 26
20 25
20 24
20 23
20 22
21 22
21 21
20 63
21 62
22 62
23 62
24 62
25 62
26 63
26 64
26 65
26 66
26 67
25 68
24 68
23 68
22 68
21 68
20 67
20 66
20 65
20 64
21 64
21 63
20 106
21 105
22 105
23 105
24 105
25 105
26 106
26 107
26 108
26 109
26 110
25 111
24 111
23 111
22 111
21 111
20 110
20 109
20 108
20 107
21 107
21 106
20 149
21 148
22 148
23 148
24 148
25 148
26 149
26 150
26 151
26 152
26 153
25 154
24 154
23 154
22 154
21 154
20 153
20 152
20 151
20 150
21 150
21 149
И вот эти пустые строки между группами ну никак не могу отловить. Я даже и пробел пробовал записть out << ' ' << endl; и еще как-то .... ну не знаю прям....
А покажи код парсера.
Код:
bool isWhitespace(const string& str)
{
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
};
{
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
};
А потом обрабатываем файл:
Код:
ifstream in("contours.txt");
while( !in.eof() ) {
string str;
getline(in, str);
if( isWhitespace(str) ) {
// process data
} else {
istringstream is(str);
int x, y;
is >> x >> y;
// store x, y
}
}
while( !in.eof() ) {
string str;
getline(in, str);
if( isWhitespace(str) ) {
// process data
} else {
istringstream is(str);
int x, y;
is >> x >> y;
// store x, y
}
}
Путем установки счетчика в if( isWhitespace(str) ) { // process data} было обнаружено что это условие выполняется только один раз.... я специально убрал свой код дабы не запутывать вас...
и посмотрел бы как реагирует код на различные варианты str, т.е. смотрел бы содержимое str и как выполнится переход по условию.
Возможно, что условие выполняется не в конце, а имнно в середине парсинга файла, а вот в конце как раз не выполняется, т.к. нет пустой строки.
Приведенный код уж очень похож, на тот, что приводил я (даже до ремарок). Могу предположить, что код который ты реально используешь несколько отличается от этого, допустим из-за незначительных перестановок и т.п. Поэтому я и просил именно тот участок кода, который у тебя в программе.
P.S. Ну и на всякий случай список необходимых заголовочных файлов:
Код:
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
#include <fstream>
#include <sstream>
using namespace std;
2. Поставил точку останова напротив if( isWhitespace(str) ) { и отследил какие значения принимает str. Оказалось, что если натыкаемся на пару чисел, то str принимает значение
{ 4294967295, { }, { "20\t21" } }
а если натыкаемся на пустую строку то
{ 4294967295, { }, { "" } }
Это нормально? Откуда тут куча скобочек и постоянно повторяющееся число 4294967295? Значение str я проверял через Run->Evaluate/Modify (это среда Builder 5).
3. В конце файла пустая строка как раз есть! Просто когда я постил сообщение в форум то потерял ее. И алгоритм действительно доходит сразу до самого конца...
Код:
while( !in.eof() ) {
fscanf (считать пару чисел)
if( пара чисел == 99999999999 99999999999 ) {
обрабатываем группу
} else {
сохранить эту пару чисел в базу
}
}
fscanf (считать пару чисел)
if( пара чисел == 99999999999 99999999999 ) {
обрабатываем группу
} else {
сохранить эту пару чисел в базу
}
}
Это конечно не так изящно, да и ламерством попахивает :-) но зато думаю будет работать. Если не будет, заканчиваю карьеру програмера :-)))))))
Может наведенная ошибка?
Попробуй упрстить программу по-максимому.
Например до такой:
Код:
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
bool isWhitespace(const string& str)
{
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}
int main()
{
ofstream out("2.txt");
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < 3; i++)
{
out << 5 << '\t' << 6 << endl;
}
out << endl;
}
out.close();
ifstream in("2.txt");
while( !in.eof() ) {
string str;
getline(in, str);
if( isWhitespace(str) ) {
int y = 9;
//
// process data
//
} else {
istringstream is(str);
int x, y;
is >> x >> y;
// store x, y
}
}
}
#include <fstream>
#include <sstream>
using namespace std;
bool isWhitespace(const string& str)
{
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}
int main()
{
ofstream out("2.txt");
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < 3; i++)
{
out << 5 << '\t' << 6 << endl;
}
out << endl;
}
out.close();
ifstream in("2.txt");
while( !in.eof() ) {
string str;
getline(in, str);
if( isWhitespace(str) ) {
int y = 9;
//
// process data
//
} else {
istringstream is(str);
int x, y;
is >> x >> y;
// store x, y
}
}
}
и проверить, как будет работать в таком случае.
Код:
if( isWhitespace(str) ) {
int y = 9;
cout << y << endl;
//
// process data
//
}
int y = 9;
cout << y << endl;
//
// process data
//
}
и что? хе, хе... и ничего цифра 9 выводится 1 раз, хотя пустых строк три. Пора завязывать с этим ;-)
В итоге остановился на ламерском способе -- записать в качестве разделителей отфонарные числа, которых в принципе в программе быть не может и ориентироваться по ним. Вроде работает. Но как говорится "неприятный осадок остался" ;-)
Как вариант, может быть проблема в используемой реализации STL.
Но а если вместо
if( isWhitespace(str) ) {
написать
if(str.length() < 3) {
?
Ведь сбоит эта ф-ия. Вообще-то из нее в данном случае польза нулевая.
Я бы для интереса убедился, что find_first_not_of работает неверно. Тогда можно было бы открыто говорить о баге в данной реализации STL.
А далее можно двинуться двумя путями:
1) сложный - воспользоваться другой реализацией STL;
2) простой - реализовать isWhitespace иначе, например, явным перебором всех знаков в строке и сравнении их с пробельными. Если доходим до конца строки не встретив ни одного непробельного символа, возвращаем true, иначе - false.
Код:
bool isWhitespace(const string& str)
{
if (str.size() == 0) return true;
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}
{
if (str.size() == 0) return true;
return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}
если не поможет, то можно полностью переписать так:
Код:
bool isWhitespace(const string& str)
{
for(int i = 0; i<str.size(); ++i) {
switch(str)
{
case ' ':
case '\t':
case '\v':
case '\r':
case '\n':
break;
default:
return false;
}
}
return true;
}
{
for(int i = 0; i<str.size(); ++i) {
switch(str)
{
case ' ':
case '\t':
case '\v':
case '\r':
case '\n':
break;
default:
return false;
}
}
return true;
}