Отправляет email-рассылки с помощью сервиса Sendsay

[prg] C++. Определение размера диска

Здравствуйте, уважаемые!

Написал коротенькую программку, которая в текстовый файл должна сохранять
размер заданного диска и его свободный объем. Программа компилируется, но
выдает ошибку при запуске - по всей видимости, , в программе какая-то
логическая ошибка, но какая, я пока не разобрался. Посмотрите, пожалуйста:

#include <windows.h>

#include <iostream>

#include <fstream>

#include <string>

#include <stdlib.h>

using namespace std;

int main () {

ofstream outfile("out.txt");

DWORD FreeBytesAvailable;

DWORD TotalNumberOfBytes;

DWORD TotalNumberOfFreeBytes;

string sDisk="C:\\";

BOOL flag = GetDiskFreeSpaceEx(

(LPCSTR)sDisk.c_str(),

(PULARGE_INTEGER)&FreeBytesAvailable,

(PULARGE_INTEGER)&TotalNumberOfBytes,

(PULARGE_INTEGER)&TotalNumberOfFreeBytes

);

if (flag != 0) {

outfile << "Свободно: " << (unsigned long)TotalNumberOfFreeBytes << endl;

outfile << "Размер диска: " << (unsigned long)TotalNumberOfBytes << endl;

}

else outfile << "Размер диска определить не удалось!" << endl;

outfile.close();

return 0;

}

Администратор Самарского голосового чата,
Самарского сервера LKF-книг
Грызунов Александр Викторович.

Программа для скачивания LKF-книг с Самарского сервера:
http://www.samaraobs.ru/lkf/lkf_start.exe
Программа для общения в Самарском голосовом чате:
http://samaraobs.ru/chat/TeamTalk.exe

Ответить   Sat, 9 Nov 2013 14:32:42 +0400 (#2866612)

 

Ответы:

Добрый день!
Могу ошибатся но по-моему dword это 32-х битовый тип. Т.е. значения от
-2 миллиарда с небольшим до +2 миллиарда с небольшим. Учитывая современные
объёмы жёстких дисков, значения в переменных будут намного больше. Так
что значения в dword в runtime превратятся в неизвестно что. Лучше использовать
Long или ему подобные. Уже не помню, но какие-то аналоги есть.

Ответить   Sat, 09 Nov 2013 15:52:38 +0400 (#2866704)

 

Приветствую всех.

Логическая ошибка не в программе, а в голове у программиста и заключается она
в отсутствии привычки читать документацию прежде, чем что-либо кодить:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx

В частности:
The values obtained by this function are of the type ULARGE_INTEGER.
Do not truncate these values to 32 bits.

Посмотрите также в документации, что представляет собой тип ULARGE_INTEGER и
вам станет очевиден тот кошмар, который вы сотворили собственными руками.

Анатолий.

Ответить   "i_chay" Sat, 9 Nov 2013 20:11:46 +0300 (#2866828)

 

Здравствуйте, i_chay.
Насчёт кошмара полностью согласен. уже после своего ответа перечитал
код, и ужаснулся. Кстати говоря программа при запуске не выдаёт ошибок
а вполне запускается. Оказалось что у меня установлен на компе
codeblocks в комплекте с GCC. Запустил, и как и ожидал что получился
там ужас мягко говоря.
остаётся догадыватся как это всё пережил visual c++ компилятор, не
удивлюсь если он и правда сдурел ото всего и скомпилил то что выдало ошибку.

п.с. А вообще эти WinAPI-шные типы уже при виде их сломали мозг.

Ответить   Sat, 9 Nov 2013 20:33:29 +0400 (#2866847)

 

Документацию я разумеется читал. Но из-за языкового барьера многого не
понял. Разобрался лишь в том, что тип переменных должен быть 64-разрядным,
но как это сделать нашел только сейчас, к примеру:

__int64 TotalNumberOfBytes;

Почему-то в документации на msdn очень много теории, но примеров я встречал
чрезвычайно редко. Мне опять скажут - да ты и искать-то не умеешь - да, не
умею, поэтому не позорьте меня перед всеми, а лучше подскажите где удочку
можно разыскать или удочку подремонтировать, готовая рыба мне самому не
нужна.

p.s. Программисты также как и все люди бывают разные - одни выдающиеся, а
другие на всю жизнь остаются начинающими - это я про себя :-(

С уважением
Грызунов Александр.

Ответить   Sun, 10 Nov 2013 03:31:28 +0400 (#2866974)

 

Приветствую всех.

Минимум, что вам нужно было понять, это объявление функции, написанное на языке
программирования C или C++. Непонимание именно этого языка является причиной
ошибок, а не английского.
Вторая причина -- это враждебное отношение к используемому компилятору. Это характерно
для начинающих программистов -- они всегда ведут борьбу с используемым компилятором,
считая его основным препятствием для проявления своих программерских талантов.
Вы собственными руками заткнули рот своему компилятору, применив ручное приведение
типов к аргументам функции GetDiskFreeSpaceEx().
Очевидно, что без такого приведения компилятор сообщал об ошибке из-за несоответствие
типов аргументов и используемых переменных.
Вместо того, чтобы задуматься над тем, почему компилятор выдает сообщение об
ошибке и разобраться с типом ULARGE_INTEGER, вы сказали компилятору "заткнись,
я лучше знаю, что надо" и в результате получили неработающее приложение.
Не меньшая проблема и с ручным приведением типов при выводе результатов в файл:
оператор << является перегруженным, т.е. конкретная его реализация зависит от
типа аргумента, а вы совершенно произвольным образом меняете этот тип, не задумываясь
о последствиях. Кстати, в вашем случае это совершенно бесполезно, так как DWORD
и unsign long это одно и то же:
http://msdn.microsoft.com/en-us/library/cc230318.aspx
This type is declared as follows:
typedef unsigned long DWORD, *PDWORD, *LPDWORD;

И не надо ничего искать: в VisualStudio можно поместить курсор на нужный тип
или имя функции, открыть контекстное меню и выбрать пункт "Перейти к объявлению"
(или что-то в этом роде). После чего вам останется лишь внимательно прочитать
те строки заголовочного файла, в которых объявлен интересующий вас тип или функция.
И так дальше, пока вы не выясните для себя смысл всех проблемных элементов кода.

Анатолий.

Ответить   "i_chay" Sun, 10 Nov 2013 12:11:09 +0300 (#2867148)