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

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

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

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

06.01.2012, 10:46. Просмотров 995. Ответов 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) та же проблема. С чем может быть связано?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.01.2012, 10:46     странное поведение ifstream::open()
Посмотрите здесь:

C++ Странное поведение
C++ Странное поведение getline
Странное поведение wstring C++
странное поведение указателя C++
Странное поведение new C++
C++ фантастики с ifstream.open
Странное поведение cin C++
Странное поведение функции C++
Странное поведение string C++
C++ Странное поведение указателей
C++ Странное поведение строки
Странное поведение cin C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
06.01.2012, 11:06     странное поведение ifstream::open() #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()
vital792
1989 / 1261 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
06.01.2012, 11:54  [ТС]     странное поведение ifstream::open() #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;
}
kazak
3032 / 2353 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
06.01.2012, 12:03     странное поведение ifstream::open() #4
Во-первых, чтобы проверить открылся ли файл, нужно использовать метод fstream::is_open().
Во-вторых, после закрытия файлового потока, если предполагается дальнейшее его использование, следует сбрасывать флаги состояний методом fstream::clear().
vital792
1989 / 1261 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
06.01.2012, 12:21  [ТС]     странное поведение ifstream::open() #5
Цитата Сообщение от kazak Посмотреть сообщение
следует сбрасывать флаги состояний методом fstream::clear().
спасибо, помогло. Я почему то считал что close() все это дело сбрасывает)

Добавлено через 7 минут
так же, на фоне этого странно что в linux все работает. Может ли быть такое, что в той реализации fstream которая у меня в linux clear() вызывается внутри close()?
Yandex
Объявления
06.01.2012, 12:21     странное поведение ifstream::open()
Ответ Создать тему
Опции темы

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