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

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

Войти
Регистрация
Восстановить пароль
 
vital792
1990 / 1262 / 56
Регистрация: 05.06.2010
Сообщений: 2,213
#1

странное поведение ifstream::open() - C++

06.01.2012, 10:46. Просмотров 1048. Ответов 4
Метки нет (Все метки)

Добрый день уважаемые форумчане! Подскажите, если не сложно, в чем проблема/ошибка? Есть две разные реализации одного метода:
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
/*
bool pelengSetting::getDataFromFile(string path)
{
    string tempPath;
    char str[5];
    ifstream file;
 
    lengthData = getMinFileLength(path) / sizeof(short);
    if(!lengthData) return false;
    music->lengthSignalData = lengthData;
    for(unsigned i=0; i<signalCount; i++)
    {
        signalData[i] = new short [lengthData + 1];
        _snprintf(str, 5, "%d", i+1); // sprintf(str, "%d", i+1);
        tempPath = path + "test" + str + ".dat";
        file.open(tempPath.c_str());
        if(!file.good()) // if(file.fail())
            return fail();
//      else log << "\nOpen File: " << tempPath.c_str() << '\n';
        file.read((char*)signalData[i], lengthData*sizeof(short));
        file.close();
    }
    return true;
}
*/
 
bool pelengSetting::getDataFromFile(string path)
{
    string tempPath;
    char str[5];
    FILE *file;
 
    lengthData = getMinFileLength(path) / sizeof(short);
    if(!lengthData) return false;
    music->lengthSignalData = lengthData;
    for(unsigned i=0; i<signalCount; i++)
    {
        signalData[i] = new short [lengthData + 1];
        _snprintf(str, 5, "%d", i+1); // sprintf(str, "%d", i+1);
        tempPath = path + "test" + str + ".dat";
        file = fopen(tempPath.c_str(), "rb");
        if( !file )
            return fail();
//      else log << "\nOpen File: " << tempPath.c_str() << '\n';
        fread(signalData[i], sizeof(short), lengthData, file);
        fclose(file);
    }
    return true;
}
Вроде все почти одинаково, но первый (в комментариях) не работает. Причем все нормально срабатывает на первом шаге цикла, а на втором, то есть при открытии файла test2.dat получаю fail. (err,hr в watch показывает S_OK). Использую visual studio 2008. Кстати, в linux, на gcc все отлично компилируется и работает. Проблема именно в windows, и именно в этой связке { file.open() file.read() file.close() }. На втором шаге она не работает. На minGW (windows) та же проблема. С чем может быть связано?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.01.2012, 10:46
Здравствуйте! Я подобрал для вас темы с ответами на вопрос странное поведение ifstream::open() (C++):

фантастики с ifstream.open - C++
там написано &quot;When using std::string to hold the filename, you must use .c_str() before passing it to this constructor.&quot; но у меня string...

Странное поведение new - C++
Объясните почему оператор new выделяет неверное количество памяти? # include &lt;iostream&gt; using namespace std; char* interpitator( int...

Странное поведение - C++
Здравствуйте еще раз :) Теперь возникла другая непонятка. Есть класс StringParser, объекты которого умеют разбивать строку на подстроки,...

Странное поведение cin - C++
Перегружаю оператор ввода следующим образом: #include &lt;iostream&gt; using namespace std; class Vector2D { public: ...

Странное поведение функции - C++
Здравствуйте! Я взялась за реализацию метода Крылова для нахождения коэффициентов характеристического полинома. Написала программу, но...

Странное поведение указателей - C++
Здравствуйте, может кто-нибудь объяснить столь странное поведение указателя. Вот код. int main() { const int Width = 3; ...

4
-=ЮрА=-
Заблокирован
Автор FAQ
06.01.2012, 11:06 #2
Цитата Сообщение от vital792 Посмотреть сообщение
getMinFileLength(path)
- зачем эта функция если string сам по себе оснащён методом length() который возращает длинну строки lengthData = (short)path.length();

Цитата Сообщение от vital792 Посмотреть сообщение
FILE *file;
- сочетание Си и плюсов - плохой тон в программировании, либо Си либо С++

Цитата Сообщение от vital792 Посмотреть сообщение
_snprintf(str, 5, "%d", i+1);
- чё за изощрения - sprintf спокойно отработает sprintf(str, "%d", i+1); правда ваша char s должна иметь 6 символов (не забівайте о ноль-терминаторе строки)
C++
1
2
char s[6];
sprintf(str, "%d", i+1);
правда я бы выделял ну скажем 8 символов char s[16]; мы работаем в 21 веке и экономить 2 чара в данном алгоритме вообще бессмысленно, это раньше за каждый байт билиськода бились. Кстати INT_MAX равен +2147483647 - єто раз два...10 разрядов + ноль терминатор и думаю разряд на знак как раз 12 символов в s надо

В функциях с коментами вижу что изначально на плюсах писали, зачем отказались???
Цитата Сообщение от vital792 Посмотреть сообщение
file.open(tempPath.c_str());
* * * * * * * * if(!file.good())
Цитата Сообщение от vital792 Посмотреть сообщение
file.read((char*)signalData[i], lengthData*sizeof(short));
думаю неверное чтение

Вот мой взгляд на проблемму
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
bool getDataFromFile(string path)
{
    string tempPath;
    char str[12];
    ifstream file;
 
    lengthData = path.length();
    if(!lengthData) 
        return false;
    music->lengthSignalData = lengthData;
    for(unsigned i=0; i<signalCount; i++)
    {
        signalData[i] = new short [lengthData + 1];
        sprintf(str, "%d", i+1);
        tempPath = path + "test" + str + ".dat";
        file.open(tempPath.c_str());
        if(!file.good()) 
            return /*fail()*/false;//М.б false хотели???
        else 
        {
            log << "\nOpen File: " << tempPath.c_str() << '\n';
            file.read((char*)signalData, lengthData);
            file.close();
            signalData[lengthData] = '\0';//Не забываем обрезать строку
        }
        file.clear();        
    }
    return true;
}
Добавлено через 1 минуту
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
lengthData = path.length();
- здесь студия не требовала явного приведения к short поэтому опустил (short) перед path.length()
1
vital792
1990 / 1262 / 56
Регистрация: 05.06.2010
Сообщений: 2,213
06.01.2012, 11:54  [ТС] #3
отвечу в том же порядке.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
getMinFileLength(path)
- зачем эта функция если string сам по себе оснащён методом length() который возращает длинну строки
Функция возвращает минимальный размер файла, чтобы знать сколько памяти выделять для чтения.
Имеется некоторый набор файлов, они могут иметь разный размер, но при чтении я их как бы уравниваю по размеры самого короткого остальное отбрасываю.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- сочетание Си и плюсов - плохой тон в программировании, либо Си либо С++
именно поэтому я и хотел бы чтобы заработал первый вариант реализации метода. А второй я привел, чтобы отсечь варианты, типа неправильно задан путь, вообще отсутствуют файлы и проч. не связанные с данным методом возможные проблемы.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- чё за изощрения - sprintf спокойно отработает sprintf(str, "%d", i+1); правда ваша char s должна иметь 6 символов (не забівайте о ноль-терминаторе строки)
в общем конечно я согласен. Так и было вначале, это Cаттер меня смутил своим " никогда не используйте sprintf " )

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
правда я бы выделял ну скажем 8 символов char s[16]; мы работаем в 21 веке и экономить 2 чара в данном алгоритме вообще бессмысленно, это раньше за каждый байт билиськода бились. Кстати INT_MAX равен +2147483647 - єто раз два...10 разрядов + ноль терминатор и думаю разряд на знак как раз 12 символов в s надо
вообще, цифра добавляемая к имени файла у меня будет числом файлов, а я уверен, что за 100 никогда не перевалит, так что 5 это еще с запасом. Файлы представляют из себя смоделированные бинарные данные "как бы" снятые с каналов антены
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
В функциях с коментами вижу что изначально на плюсах писали, зачем отказались???
написал выше.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
file.read((char*)signalData[i], lengthData*sizeof(short));
думаю неверное чтение
в дампе памяти все верно. К тому же повторюсь, в линуксе все работает на ура. Поэтому я был очень удивлен, что в винде не заработало.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
return /*fail()*/false;//М.б false хотели???
fail() у меня метод. Возвращает false и сбрасывает поле "статус" в ошибку.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
file.read((char*)signalData, lengthData);
signalData это у меня должна получиться матрица signalData [signalCount][lengthData]

Добавлено через 17 минут
Заранее предвижу, что экстрасенсы в отпуске))
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
unsigned pelengSetting::getMinFileLength(string path)
{
    unsigned length = -1;
    ifstream file;
    string tempPath;
    char str[10];
    for(unsigned i=0; i<signalCount; i++)
    {
        sprintf(str, "%d", i+1);
        tempPath = path + "test" + str + ".dat";
        file.open(tempPath.c_str());
        if(!file)
        {
//          log << "Error open file " << tempPath.c_str( )<< "\n";
            status = false;
            length = 0;
            break;
        }
        else
        {
            file.seekg(0, ios::end);
            if(file.tellg()<length) length = file.tellg();
            file.close();
        }
    }
    return length;
}
 
bool pelengSetting::fail()
{
    status = false;
    return false;
}
0
kazak
3035 / 2356 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
06.01.2012, 12:03 #4
Во-первых, чтобы проверить открылся ли файл, нужно использовать метод fstream::is_open().
Во-вторых, после закрытия файлового потока, если предполагается дальнейшее его использование, следует сбрасывать флаги состояний методом fstream::clear().
1
vital792
1990 / 1262 / 56
Регистрация: 05.06.2010
Сообщений: 2,213
06.01.2012, 12:21  [ТС] #5
Цитата Сообщение от kazak Посмотреть сообщение
следует сбрасывать флаги состояний методом fstream::clear().
спасибо, помогло. Я почему то считал что close() все это дело сбрасывает)

Добавлено через 7 минут
так же, на фоне этого странно что в linux все работает. Может ли быть такое, что в той реализации fstream которая у меня в linux clear() вызывается внутри close()?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2012, 12:21
Привет! Вот еще темы с ответами:

Странное поведение транслятора - C++
В следуюшем примере код компилируется нормально, но объект класса b не содается (пробывал на Visual studio 10 и на Borland builder 5), что...

Странное поведение указателя - C++
Здравствуйте, наткнулся на непонятное мне поведение указателя или точнее менеджера памяти. Есть код: #include &lt;iostream&gt; #include...

Странное поведение cin - C++
Есть класс, в нем есть два текстовых private члена, friend-оператор&gt;&gt; и friend-функция getline для записи в эти члены. Но когда в main.cpp...

Странное поведение строки - C++
Есть класс со связным списком(в связных списках символы)(файл1). Перегружаю оператор сложения для объектов этих классов так, чтобы оператор...


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

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

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