Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пишу простенький файловый менеджер, возник ряд вопросов. Язык С++

307
25 июля 2008 года
Artem_3A
863 / / 11.04.2008
Пишу простенький файловый менеджер, в целях самообразования, возник ряд вопросов. Язык С++, среда Microsoft Visual Studio 2005.

Возник такой вопрос, для атрибутов файлов существуют константные обозначения FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_COMPRESSED и т.д. а если файл является, допустим, архивным и скрытым да еще и только для чтения? В заголовочном файле winnt.h, где данные константы объявляются, ни чего подобного нет, из чего предполагаю, что в данном случае константы как то комбинируются!
Искал везде где только можно, ни какой информации не нашел, может кто сталкивался и разрешит мои затруднения?

И еще возник вопрос: каким образом получить список доступных устроиств хранения данных? Например сколько дисков, есть ли в сидироме диск, доступны ли флэш диски. И как обновлять данный список автоматически при его изменение.

И так же еще: как узнать какая программа работает с конкретным файлом и как по желанию пользователя запустить ее, что бы она начала работу именнно с этим файлом?
7.6K
25 июля 2008 года
sergeinv
3 / / 07.05.2004
1. Аттрибуты файлов вроде как представимы в виде байта(ов).
Т.е. тогда ты должен обрабатывать результат функции

DWORD GetFileAttributes(
LPCTSTR lpFileName // address of the name of a file or directory
);

операторами побитового сдвига << и >>
Определенный бит отвечает за определённый аттрибут файла

2. Про диски

а)DWORD GetLogicalDrives(VOID)

DWORD GetLogicalDriveStrings(

DWORD nBufferLength, // size of buffer
LPTSTR lpBuffer // address of buffer for drive strings
);

б)UINT GetDriveType(

LPCTSTR lpRootPathName // address of root path
);

в) Информацию о вставленном диске можно попробовать получить посредтвом чтения с устройства как с файла.
Способ может не самый удобный :)

CreateFile()
SetFilePointer()
ReadFile()

Если диск будет вставлен, то ты будешь читать диск полностью, если нет,
то там ничего не будет :)

3. И про запуск программ по желанию пользователя.
Таким способом тебе даже не нужно знать про привязки программ к конкретному типу файлов
(А вообще привязки в реестре HKCR)

HINSTANCE ShellExecute(

HWND hwnd, // handle to parent window
LPCTSTR lpOperation, // pointer to string that specifies operation to perform
LPCTSTR lpFile, // pointer to filename or folder name string
LPCTSTR lpParameters, // pointer to string that specifies executable-file parameters
LPCTSTR lpDirectory, // pointer to string that specifies default directory
INT nShowCmd // whether file is shown when opened
);
307
26 июля 2008 года
Artem_3A
863 / / 11.04.2008
Спасибо большое! Ты мне очень помог! Только если не сложно поясни с атрибутами. Они действительно представлены в виде байтов а именно:
 
Код:
FILE_ATTRIBUTE_READONLY     0x00000001
FILE_ATTRIBUTE_HIDDEN           0x00000002
FILE_ATTRIBUTE_SYSTEM               0x00000004
FILE_ATTRIBUTE_DIRECTORY        0x00000010
FILE_ATTRIBUTE_ARCHIVE              0x00000020
........................................................................
........................................................................

В таком случая на сколько я тебя понял код будет:
 
Код:
DWORD df = GetFileAttributes("C:\\MyFile.txt");
    int n;
    for( int i = 0; i < 26; i++ )
    {
         n = ((df>>i)&0x00000001);
         //дальше сравниваем с константами
    }

Если я не прав, поправь меня как надо, так как в верности сомневаюсь.

Еще осталась проблема с тем как обработать изменение количества доступных дисков, на сколько я понимаю, при появление или отключения устройства должно посылаться некоторое сообщение, в таком случае возникает вопрос, какое это сообщение и как его правильно обработать?

И возник еще один вопрос, как получить иконку, для каждого типа файлов не посредтвенно из файла?
3.7K
26 июля 2008 года
0nni
326 / / 24.06.2008
По поводу атрибутов- не сильно знаком с си, объясню на пальцах:

 
Код:
FILE_ATTRIBUTE_READONLY      00000001
FILE_ATTRIBUTE_HIDDEN        00000010
FILE_ATTRIBUTE_SYSTEM        00000100
...

Не нужно ничег сдвигать нужно просто умножить (как учил Буль) твой df на какую-нибудь из констант и проверить результат:
 
Код:
if (( df & FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY) {
...
}

Тоесть допустим у тебя df = 3 те(00000011) тогда после умножения на 00000001 ты получишь 00000001.

2. Диски посылается сообщение WM_DEVICECHANGE описание смотри в справке

3.Иконку можно получить через ExtractAssociatedIcon - к сожаления не знаю где в MSVC++она описана =(
307
26 июля 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: 0nni

Не нужно ничег сдвигать нужно просто умножить (как учил Буль) твой df на какую-нибудь из констант и проверить результат:
 
Код:
if (( df & FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY) {
...
}

Тоесть допустим у тебя df = 3 те(00000011) тогда после умножения на 00000001 ты получишь 00000001.



Правильно, но ведь надо получить атрибуты типа скрытый+архивный, в таком случае мы вообще не получим атрибута, твоим способом, так как если атрибуты комбинируются, то функция вернет число - битовую маску, к примеру, когда писал программу для поиска файлов на Builder'е то имел такие результаты, если мне не изменяет память 128 это системный, а 317 это уже скрытый системный!

Спасибо, с остальным ты мне очень помог!=)

1.8K
26 июля 2008 года
igor_nf
256 / / 13.12.2006
Цитата: Artem_3A
Правильно, но ведь надо получить атрибуты типа скрытый+архивный, в таком случае мы вообще не получим атрибута, твоим способом..



А что кроме побитового умножения ничего не существует ещё ?

 
Код:
if (df & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN))
..<файл скрытый и архивный>
307
26 июля 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: igor_nf
А что кроме побитового умножения ничего не существует ещё ?

 
Код:
if (df & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN))
..<файл скрытый и архивный>



Кстати, это вариант, не уверен что будет работать, но попробовать стоит...

1.9K
26 июля 2008 года
max_dark
256 / / 11.11.2005
Писал для своих нужд, мож пригодится:
Код:
struct file_attribute {
    bool is_readonly;
    bool is_hidden;
    bool is_system;
    bool is_directory;
    bool is_archive;
    bool is_encripted;
    bool is_normal;
    bool is_temporary;
    bool is_sparse_file;
    bool is_reparse_point;
    bool is_compressed;
    bool is_offline;
    bool is_not_indexed;
};

bool get_attribute(TCHAR* fname, struct file_attribute & fa) {
    DWORD attr=GetFileAttributes(fname);
    bool result = ( attr != 0xFFFFFFFF );
    if (result) {
        fa.is_readonly      = ( 0 != ( attr & FILE_ATTRIBUTE_READONLY ) );
        fa.is_hidden        = ( 0 != ( attr & FILE_ATTRIBUTE_HIDDEN ) );
        fa.is_system        = ( 0 != ( attr & FILE_ATTRIBUTE_SYSTEM ) );
        fa.is_directory     = ( 0 != ( attr & FILE_ATTRIBUTE_DIRECTORY ) );
        fa.is_archive       = ( 0 != ( attr & FILE_ATTRIBUTE_ARCHIVE ) );
        fa.is_encripted     = ( 0 != ( attr & FILE_ATTRIBUTE_ENCRYPTED ) );
        fa.is_normal        = ( 0 != ( attr & FILE_ATTRIBUTE_NORMAL ) );
        fa.is_temporary     = ( 0 != ( attr & FILE_ATTRIBUTE_TEMPORARY ) );
        fa.is_sparse_file   = ( 0 != ( attr & FILE_ATTRIBUTE_SPARSE_FILE ) );
        fa.is_reparse_point = ( 0 != ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) );
        fa.is_compressed    = ( 0 != ( attr & FILE_ATTRIBUTE_COMPRESSED ) );
        fa.is_offline       = ( 0 != ( attr & FILE_ATTRIBUTE_OFFLINE ) );
        fa.is_not_indexed   = ( 0 != ( attr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ) );
    }
    return result;
}
307
27 июля 2008 года
Artem_3A
863 / / 11.04.2008
Относительно атрибутов, если кому то еще понадобиться, вот рабочий вариант.(получен путем неимоверных извращений над текстовиком:D;):D)

Код:
#include <iostream>
#include <windows.h>

using namespace std;

int main(void)
{
    DWORD df = GetFileAttributes("C:\\Новый текстовый документ (2).txt");
    cout << df<< endl;
    if((df&FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)
        cout << "Read only"<< endl;
    if((df&FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)
        cout << "Hidden"<< endl;
    system("pause");
    return EXIT_SUCCESS;
}


Может тупой вопрос, но все же сам ни как не могу понять, какая констанка соответсвует в атрибутах ярлыку?:confused:
3.7K
27 июля 2008 года
0nni
326 / / 24.06.2008
Цитата: Artem_3A

Может тупой вопрос, но все же сам ни как не могу понять, какая констанка соответсвует в атрибутах ярлыку?:confused:



Ярлык это просто файл (anyfile) с расширением .lnk, просто он видной по особому интерпретируется, если пошаманить, то можно открыть черех hex и почитать.

1.9K
27 июля 2008 года
max_dark
256 / / 11.11.2005
Я сам интересуюсь импортом ярлыков, но пока не очень :( ResolveLink Если кто, что знает, отпишитесь, пожалуйста
307
29 июля 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: max_dark
Я сам интересуюсь импортом ярлыков, но пока не очень :( ResolveLink Если кто, что знает, отпишитесь, пожалуйста



Присоединяюсь, инфы по этому вопросу почти нет!

14
29 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Artem_3A
Присоединяюсь, инфы по этому вопросу почти нет!


В теме http://forum.codenet.ru/showthread.php?t=42593 я вчера ответил, смотрите внимательнее

307
02 августа 2008 года
Artem_3A
863 / / 11.04.2008
Возникло такое затруднение.
Код:
#include <windows.h>
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hf;
    hf=FindFirstFile("c:\\*", &FindFileData);
    if (hf!=INVALID_HANDLE_VALUE)
    {
        do
        {
            cout << FindFileData.cFileName << endl;
        }
        while (FindNextFile(hf,&FindFileData)!=0);
        FindClose(hf);
    }
    system("pause");
    return EXIT_SUCCESS;
}


В Dev-C++, собственно как и в MVS C++ 6.0, данный код прекрасно компилиться и работает!
Однако в MVS 2005 C++ и MVS 2008 C++ я получаю следующую ошибку

 
Код:
1>c:\users\ааа\documents\visual studio 2008\projects\findfile\findfile\findfile.cpp(17) : error C2664: 'FindFirstFileW' : cannot convert parameter 1 from 'const char [5]' to 'LPCWSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


C WCHAR все работает, но хотелось бы узнать в чем дело, и можно это как то обойти? Я так догадываюсь что это связано с Unicode...:confused:
1.9K
02 августа 2008 года
max_dark
256 / / 11.11.2005
Похоже, что в VS2008 по умолчанию используется UNICODE
Для переносимости кода в таком случае использовать макрос TEXT()
 
Код:
hf=FindFirstFile(TEXT("c:\\*"), &FindFileData);
307
02 августа 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: max_dark
Похоже, что в VS2008 по умолчанию используется UNICODE
Для переносимости кода в таком случае использовать макрос TEXT()
 
Код:
hf=FindFirstFile(TEXT("c:\\*"), &FindFileData);



Ясно, спасибо.
А если мне допустим надо?

 
Код:
bool searchFile(const char* path)
{
     <skip>
     hf = FindFirstFile(path, &FindFileData);
     <skip>
}
1.9K
02 августа 2008 года
max_dark
256 / / 11.11.2005
Используй TCHAR вместо char:
При юникоде будет использоватся wchar_t, а без юникода - char
307
02 августа 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: max_dark
Используй TCHAR вместо char:
При юникоде будет использоватся wchar_t, а без юникода - char



Ясно, спасибо, хотелось бы как то без wchar обойтись, но видать придется!=(

1.9K
02 августа 2008 года
max_dark
256 / / 11.11.2005
Я с VS2005/2008 не работал, но предпологаю что работа с/без Unicode должна выставлятся в настройках проекта ;)

[QUOTE=Artem_3A]хотелось бы как то без wchar обойтись[/QUOTE]Интересно, чем же плох юникод?
9.4K
02 августа 2008 года
AIGrifon
165 / / 13.11.2007
Цитата: Artem_3A
Возникло такое затруднение.
Однако в MVS 2005 C++ и MVS 2008 C++ я получаю следующую ошибку

 
Код:
1>c:\users\ааа\documents\visual studio 2008\projects\findfile\findfile\findfile.cpp(17) : error C2664: 'FindFirstFileW' : cannot convert parameter 1 from 'const char [5]' to 'LPCWSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


C WCHAR все работает, но хотелось бы узнать в чем дело, и можно это как то обойти? Я так догадываюсь что это связано с Unicode...:confused:



На самом деле, если внимательно посмотреть, то, по крайней мере, в MS VS 2005 существует как функция FindFirstFileW, так и FinFirstFileA. Первая работает с юникодом, вторая - с ANSI. Чтобы упростить жизнь разработчикам специально создан макрос FindFirstFile. Если взглянуть на его описание в winbase.h:
[highlight=cpp]
#ifdef UNICODE
#define FindFirstFile FindFirstFileW
#else
#define FindFirstFile FindFirstFileA
#endif // !UNICODE
[/highlight]
то можно ясно увидеть, как решить вашу проблему. В коде лучше использовать макрос FindFirstFile, а уже при необходимости включать/отключать поддрежку юникода, например с помощью директивы undef. Аналогичная практика рапространена и для многих других функций, так что просто стоит быть любопытнее:)

307
13 августа 2008 года
Artem_3A
863 / / 11.04.2008
Столкнулся с таким, так сказать феноменом!
Есть рекурсивная функция поиска файлов по диску:
Код:
void searchFiles(const char* const adress)
{
    WIN32_FIND_DATA fn;
    HANDLE hf;
    hf = FindFirstFiles(adress, &fn);
    if(hf!=INVALID_HANDEL_VALUE)
    {
          do
          {
                if((df&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
                {
                      char* newAdress;
                       <skip>
                      .............
                       <skip>
                       searchFiles(newAdress);
                }
          }while(FindNextFiles(hf, &fn)!=0)
    }
}


Если просмотреть адреса поиска то у меня лично получилось:
 
Код:
C:\\*
C:\\Acer\*
C:\\Acer\.\*
C:\\Acer\.\.\*
C:\\Acer\.\.\.\*
................................
C:\\Acer\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*


Естественно ни каких папок "." и в поминет нет. newAdress преобразовывается правильно. "." возникают именно при поиске.
Может кто нить сталкивался?:confused: И может объяснить в чем дело?
1.9K
13 августа 2008 года
max_dark
256 / / 11.11.2005
Папка "." это ссылка на текущую директорию
Те если мы находимся в папке C:\test\ есть файл test.txt, то
C:\test\test.txt и .\test.txt - одно и тоже.
Так же есть ".." - ссылка на родительскую папку. ..\test.txt для пред идущего примера будет указывать на C:\test.txt
При поиске необходимо это учитывать. Например так
 
Код:
if ((strcmp(".", currFile)=0)||(strcmp("..", currFile)=0))
  continue;
3.7K
13 августа 2008 года
0nni
326 / / 24.06.2008
Цитата: Artem_3A

Естественно ни каких папок "." и в поминет нет. newAdress преобразовывается правильно. "." возникают именно при поиске.
Может кто нить сталкивался?:confused: И может объяснить в чем дело?


На самом деле папки "." и ".." остались от дос'а и обозначают родительский каталог и на саму себя те "с:\a\b\c\.." это то же что и "c:\a\b\"
так что просто делай проверку паки на имя "." и ".."

307
13 августа 2008 года
Artem_3A
863 / / 11.04.2008
Ясно, уже разобрался методом научного тыка, но все равно спасибо!=)

Теперь такой вопрос!
Код:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include "Kfile.h"
#include <vector>

using namespace std;

void searchFiles(const char* const adress, vector<CKfile> &list);

int _tmain(int argc, _TCHAR* argv[])
{
    char* adress;
    <skip>
    vector<CKfile> list;
    searchFiles(adress, list);
    for(int i=0; i<list.size(); i++)
        cout << list.getLocation()<< endl;
    system("pause");
    return EXIT_SUCCESS;
}

void searchFiles(const char* const adress, vector<CKfile> &list)
{
    WIN32_FIND_DATAA fn;
    HANDLE hf;
    hf = FindFirstFileA(adress, &fn);
    if(hf!=INVALID_HANDLE_VALUE)
    {
        do
        {
            try
            {
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)
                    throw 1;
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
                    continue;
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM)
                    continue;
                char* newAdress;
                newAdress = new char[1000];
                strncpy(newAdress, adress, 1000);
                for(int i=0; i<strlen(newAdress); i++)
                {
                    if((newAdress=='*') || (newAdress=='\0'))
                    {
                        newAdress='\0';
                        break;
                    }
                }
                if(strcmp(fn.cFileName, ".")==0)
                    continue;
                if(strcmp(fn.cFileName, "..")==0)
                    continue;
                strcat(newAdress,fn.cFileName);
                for(int i=0; i<strlen(newAdress)+1; i++)
                {
                    if(newAdress=='\0')
                    {
                        newAdress='\\';
                        newAdress[i+1]='*';
                        newAdress[i+2]='\0';
                        break;
                    }
                }
                searchFiles(newAdress, list);
                delete newAdress;
            }
            catch(int e)
            {
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM) != FILE_ATTRIBUTE_SYSTEM)
                {
                    CKfile temp;
                    temp.setData(fn, adress);
                    list.push_back(temp);
                }
            }
        }while(FindNextFileA(hf, &fn)!=0);
        FindClose(hf);
    }
}


temp.setData(fn, adress);
Код:
void CKfile::setData(const WIN32_FIND_DATAA temp, const char* path)
{
    for(int i=0; i<260; i++)
    {
        name=temp.cFileName;
        if(temp.cFileName=='\0')
            break;
    }
    size = temp.nFileSizeHigh*(1+MAXDWORD) + temp.nFileSizeLow;
    strncpy(location, path, 10000);
    location[strlen(location)]='\0';
    strncat(location, name, (10000-strlen(location)));
    lastAccesTime = ConvertTime(temp.ftLastAccessTime);
    createTime = ConvertTime(temp.ftCreationTime);
    if((temp.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
        dirFlag = true;
    return;
}


В процессе вылетает:
 
Код:
Windows has triggered a breakpoint in Searchfiles.exe.

This may be due to a corruption of the heap, and indicates a bug in Searchfiles.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information


Причина кроется в этом участке кода:
 
Код:
CKfile temp;
temp.setData(fn, adress);
list.push_back(temp);

А именно в list.push_back(temp);
В чем именно я так и не могу понять!=(
Кто знает, подскажите где я туплю!
307
15 августа 2008 года
Artem_3A
863 / / 11.04.2008
Вопрос в догонку, может кто посоветует книгу по WinForm на С++!:)
1.9K
18 августа 2008 года
max_dark
256 / / 11.11.2005
Проблема скорее всего кроется в отсутствии конструктора копирования для класса CKfile
Artem_3A, смогу сказать точнее, когда выложишь полный код класса
307
19 августа 2008 года
Artem_3A
863 / / 11.04.2008
Спасибо max_dark, ты оказался совершенно прав!:) Сам не понимаю как упустил это из виду!:mad:
1.9K
19 августа 2008 года
max_dark
256 / / 11.11.2005
Совсем забыл: у тебя здесь еще утечка памяти:
Код:
{
    WIN32_FIND_DATAA fn;
    HANDLE hf;
    hf = FindFirstFileA(adress, &fn);
    if(hf!=INVALID_HANDLE_VALUE)
    {
        do
        {
            try
            {
                if(strcmp(fn.cFileName, ".")==0) continue; // <<<
                if(strcmp(fn.cFileName, "..")==0) continue; // <<<
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)
                    throw 1;
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
                    continue;
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM)
                    continue;
                char* newAdress;
                newAdress = new char[1000];
                strncpy(newAdress, adress, 1000);
                for(int i=0; i<strlen(newAdress); i++)
                {
                    if((newAdress=='*') || (newAdress=='\0'))
                    {
                        newAdress='\0';
                        break;
                    }
                }
                // if(strcmp(fn.cFileName, ".")==0) continue; // <<<
                // if(strcmp(fn.cFileName, "..")==0) continue; // <<<
                strcat(newAdress,fn.cFileName);
                for(int i=0; i<strlen(newAdress)+1; i++)
                {
                    if(newAdress=='\0')
                    {
                        newAdress='\\';
                        newAdress[i+1]='*';
                        newAdress[i+2]='\0';
                        break;
                    }
                }
                searchFiles(newAdress, list);
                delete newAdress;
            }
            catch(int e)
            {
                if((fn.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM) != FILE_ATTRIBUTE_SYSTEM)
                {
                    CKfile temp;
                    temp.setData(fn, adress);
                    list.push_back(temp);
                }
            }
        }while(FindNextFileA(hf, &fn)!=0);
        FindClose(hf);
    }
}
Обрати внимание на помеченные // <<< строки
307
23 августа 2008 года
Artem_3A
863 / / 11.04.2008
Спасибо max_dark!=) На самом деле там еще две утечки памяти помимо тех которые ты мне указал!=(
У меня теперь возникло два, так сказать, финальных вопроса!

Во первых, как получить дескриптор файла зная полный путь к нему, включая имя?
Во вторых, меня интересует как правильнее можно изменить права доступа к файлу?
И в третьих, что выполниться быстрее? Копирование "в ручную", пробегая циклом и копируя, или через функцию strcmp?(char*)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог