Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с fopen(), fprintf(), VS 2005 
V
    Опции темы
Rickert
Дата 19.11.2006, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Недавно перешёл на VS 2005, раньше в VS 2003 не было никакх проблема с fopen и fprintf, а теперь такая песня:
Открываю файл:
Код

...
FILE* file = fopen(chr, "w+");

if (!file)
{
    AfxMessageBox(L"Не могу открыть файл настроек для записи!");
    return;
}
...

Мне компилятор выдаёт предупреждение:
Цитата

... : warning C4996: 'fopen' was declared deprecated
... : see declaration of 'fopen'
Message: 'This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

После чего пытаюсь записать в открытй файл:
Код

fprintf(file, "%d %d %s %d %s\n", tmp->num, tmp->name.GetLength(), tmp->name.GetBuffer(), tmp->path.GetLength(), tmp->path.GetBuffer());

tmp->num - int
tmp->name и tmp->path - CString
В них все значения правильные, но в файл она пишет след. значения:
Цитата

0 10 #G0AB=8:  41 E

 smile

Добавлено @ 11:13 
Только что пробовал проделать всё через API'шные функции:
Код

...
    HANDLE hndl = CreateFile(str.GetBuffer(), GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
    
    LPDWORD l = new DWORD;
    CString str;

        str.Format(L"%d %d %s %d %s\n", tmp->num, tmp->name.GetLength(), tmp->name.GetBuffer(), tmp->path.GetLength(), tmp->path.GetBuffer());
        WriteFile(hndl, str.GetBuffer(), str.GetLength(), l, 0);
...

Смотрю в дебаге str - значения нормально прописались, а в файле всё равно белебердень.

Это сообщение отредактировал(а) Rickert - 19.11.2006, 11:14


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
nerezus
Дата 19.11.2006, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: нет
Всего: 43



Цитата

... : warning C4996: 'fopen' was declared deprecated
... : see declaration of 'fopen'
Message: 'This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'


Это очередная гнилая попытка M$ подмять стандарт под себя:

Код

nerezus@k1b:~/web/d2$ cat test.c         
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fh = fopen("test.c", "r");
    if (!fh) {
        printf("Жопа");
    }
    return 0;
}
nerezus@k1b:~/web/d2$ gcc -o test test.c         
nerezus@k1b:~/web/d2$ ./test 
nerezus@k1b:~/web/d2$ 



Код

nerezus@k1b:~/web/d2$ cat test.c 
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fh = fopen_s("test.c", "r");
    if (!fh) {
        printf("Жопа");
    }
    return 0;
}
nerezus@k1b:~/web/d2$ gcc -o test test.c 
test.c: In function ‘main’:
test.c:5: warning: initialization makes pointer from integer without a cast
/tmp/ccKHTd07.o: In function `main':
test.c:(.text+0x21): undefined reference to `fopen_s'
collect2: ld returned 1 exit status
nerezus@k1b:~/web/d2$ 



--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
Rickert
Дата 19.11.2006, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



С этим ясно, а что по поводу неверно - записываемого значения?


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Rickert
Дата 19.11.2006, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Код

fclose();

С переводом значения из wchar_t в char smile 

Это сообщение отредактировал(а) Rickert - 19.11.2006, 14:09


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Rickert
Дата 19.11.2006, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Интересно, что при использовании API'шных функций, всё-таки информация записывается неправильно:
Код

        HANDLE hndl = CreateFile(str.GetBuffer(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_FLAG_WRITE_THROUGH, 0);
        str.Format(L"%d %d %s %d %s\n", tmp->num, tmp->name.GetLength(), tmp->name.GetBuffer(), tmp->path.GetLength(), tmp->path.GetBuffer());
        WriteFile(hndl, str.GetBuffer(), str.GetLength(), l, 0);
        CloseHandle(hndl);


Почему smile 


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Любитель
Дата 20.11.2006, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



name и path у тебя в уникоде? Если сите просто CStringб то вероятно да. Посему либо конверть в анси, либо смотри файлик в уникоде  smile 


--------------------
PM MAIL ICQ Skype   Вверх
Rickert
Дата 21.11.2006, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Любитель, не знаю. А по умолчанию CString хранит в юникоде разве?
Цитата

Посему либо конверть в анси

Как?
Цитата

либо смотри файлик в уникоде

Понимаешь, там даже значений никаких нет. Там сначала идёт длинна строки, а потом строка. Смотри, видишь длинну 43? А после неё всего лишь два символа. Как ты этот файл не просматривай, но если там никаких значений, то они не появятся из ниоткуда.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
takedo
Дата 21.11.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Цитата

А по умолчанию CString хранит в юникоде разве?
 В 2005 студии проект по умолчанию юникодный. Ты привыкни к макросам _T("Твой текст"), или _TEXT("То же самое");


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
Любитель
Дата 21.11.2006, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



CString это не конкретный тип. Он типодефится либо в CStringA либо в CStringW. Сделай тупую проверку: попробуй прочитать теперь из файла (программно) и выведи как-нибудь на экран. Или (в данном случае разумней) используй CStringA или std::string.


--------------------
PM MAIL ICQ Skype   Вверх
Rickert
Дата 23.11.2006, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Цитата

В 2005 студии проект по умолчанию юникодный. Ты привыкни к макросам _T("Твой текст"), или _TEXT("То же самое"); 

Пробовал все варианты уже _T, _TEXT, L"".

Цитата(Любитель @  21.11.2006,  17:28 Найти цитируемый пост)
CString это не конкретный тип. Он типодефится либо в CStringA либо в CStringW. Сделай тупую проверку: попробуй прочитать теперь из файла (программно) и выведи как-нибудь на экран. Или (в данном случае разумней) используй CStringA или std::string.

Код

    CFile file;
    file.Open(str.GetBuffer(), CFile::modeCreate | CFile::modeWrite);

    CStringA str2;

    str2.Format(L"%d %d %s %d %s\n", tmp->num, tmp->name.GetLength(), tmp->name.GetBuffer(), tmp->path.GetLength(), tmp->path.GetBuffer());
    file.Write(str2.GetBuffer(), str2.GetLength());
    file.Close();

CStringA str2 - нулевой результат, тот же глюк.
CStringW str2 - нулевой результат, тот же глюк.
 smile 

Это сообщение отредактировал(а) Rickert - 23.11.2006, 16:47


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Earnest
Дата 24.11.2006, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



В чем глюк-то?
Из беглого просмотра темы не поняла.



--------------------
...
PM   Вверх
Rickert
Дата 24.11.2006, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Глюк в том, что в переменной хранятся нормальное значение строки(смотрю в дебаге), а при любом выводе в файл(FILE, CFile, CreateFile) - в файл пишется белеберда.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Earnest
Дата 24.11.2006, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Файл текстовый или двоичный? Что именно видишь в файле? Имей в виду, что юникодные или русские символы могут выглядеть совсем не так, как ты ожидаешь. 
Кстати, строку лучше писать вместе с завершающим нулем, т.е. GetLength()+1 символов. Либо писать перед строкой ее длину. Иначе как читать потом будешь?

Кроме того, в Юникоде длина символа = 2 байта, так что в файл нужно писать соответственно:

Код

// если str - это CString
file.Write (str.GetBuffer(), (str.GetLength()+1)*sizeof(TCHAR));




--------------------
...
PM   Вверх
Любитель
Дата 25.11.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



А ещё вспомни, что Format типобезопасностью не радует (т. к. юзает (w)snprintf) => %s внаглую интерпретирует строку не как юникод. Поэтому ни в коем случае не используй юникод (или другие форматные символы ставь -> см. MSDN), а лучше откажись от нетипобезопасных функций (методов).


--------------------
PM MAIL ICQ Skype   Вверх
Rickert
Дата 25.11.2006, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Цитата(Earnest @  24.11.2006,  20:13 Найти цитируемый пост)
Файл текстовый или двоичный? Что именно видишь в файле? Имей в виду, что юникодные или русские символы могут выглядеть совсем не так, как ты ожидаешь. 

Посмотри то, что я постил до этого - там на все вопросы ответы. Файл не бинарник. Вижу в нём вышеуказнное.
 smile 


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1288 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.