Имеется задача, считывать с файла по одной строке, в некотором государстве посоветовали делать мапинг но я в этом не шарю, кто то может привести пример такого кодеса? Сам ненашел...но нужно обязательно делать это на WinAPI, парсить строку на переходы строк (\r и \n) нехочется но возможно можно както это сделать с мапингом?
нашел вот такой кодес но он читает посимвольно, а мне нужно всю строку и так одну за другой Код (C++): #include <Windows.h> int main() { HANDLE hFile = CreateFile("test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); int sizeChars = GetFileSize(hFile, NULL); HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); char* lpText = (char*) MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); char* lpCurrent = lpText; while(lpCurrent - lpText < sizeChars ) { char* lpLineStart = lpCurrent; while (lpCurrent - lpText < sizeChars && *lpCurrent != 0xD) // первое условие увы, необходимо , так как в конце последней строки может не быть CR { MessageBox(0,lpCurrent, lpCurrent, MB_OK); lpCurrent++; } // lpLineStart - начало, (lpCurrent -1) - конец // отладочная печать //for(char* p = lpLineStart; p < lpCurrent; p++) // putchar(*p); //putchar('\n'); //// конец отладочной печати lpCurrent += 2; } UnmapViewOfFile(lpText); CloseHandle(hFileMapping); CloseHandle(hFile); return 0; }
помогите плз правильно оформить вот этот кодес из цикла Код (C++): char *test1 = new char[24]; for(char* p = lpLineStart; p < lpCurrent; p++, test1++) { *test1 = *p;} MessageBox(0,test1, test1, MB_OK); lpCurrent += 2; надо чтоб каждую строчку вывело месаджбоксом отдельно по очереди
все разобрался вот кодес патча =)))) Код (C++): char* p = lpLineStart; for(; p < lpCurrent; p++) putchar(*p); MessageBox(0,p, p, MB_OK); putchar('\n'); вот толкьо чую что гдето там остался (\r). что если снести его в 13ой строке добавив *lpCurrent-1 != \r PS мои опасения были напрасны , все срезается в цикле тему можно закрыть
[ixTor] Слишком много скрипта. В смысле что текст большой а смысла в нём нет. Проекция файла в память это фундаментальный механизм ос. Тут часто видны примеры, где на каждой итерации в цикле выполняется обращение к файлу. Так делать нельзя, это нубство ибо не профайл. Файл отображается на память и после работы с памятью сохраняется.
почему не делается, а как делать? я лично к этому кодесу еще кучу всего должен прикрутить, ибо пишу бруНтенг, предлогаешь юзаеть фраемворки? по мойму норм, спроецировали в память и с памятью работаем=\
Да, правильно. Только там нужно учитывать что текст может быть без LF или CR, т.е. тестить второй символ за искомым, если там противоположный, его тоже пропускать, конечную строку либо копировать в буфер либо (используя PAGE_WRITECOPY доступ писать \0 прямо в память проекции), если хочешь выводить стандартными WinAPI функциями строку. Предложу еще способ это заюзать стандартный FSO и юзать метод ReadLine объекта TextStream.
Код (C++): #include <atlbase.h> #undef GetFreeSpace #import <scrrun.dll> using namespace Scripting; void startup() { { CComPtr<IFileSystem> pfs; CComPtr<ITextStream> pstm; _bstr_t bstrLine; CoInitialize(NULL); HRESULT hr = pfs.CoCreateInstance(OLESTR("Scripting.FileSystemObject")); if (SUCCEEDED(hr)) pstm = pfs->OpenTextFile(bstr_t(L"C:\\Temp\\test.txt"), IOMode::ForReading, (VARIANT_BOOL) false, TristateUseDefault); if (pstm) while (SUCCEEDED(hr = pstm->raw_ReadLine(bstrLine.GetAddress()))) MessageBox(NULL, bstrLine.GetBSTR(), NULL, NULL); } CoUninitialize(); return; };
Простите, чем автора топика не устраивают gets() из обычной Си-шки? Оно же все равно всю низкоуровневую подноготную реализует лучше, чем руками изображать-изобретать, разве нет? Разумеется при условнии что файл честно текстовый.
На сколько большой файл? Что потом делается с данными - они читаются, редактируются? Ограничена ли память? Много лет назад я писал парсер очень большого текст файла (десятки-сотни тысяч линий), для случайного чтения. Алгоритм был такой: сделать первый пасс по файлу (либо через MMF или просто банальный fread/ReadFile), и записать оффсеты всех линий в массив. Само содержимое линий в память сразу не вчитывалось. Потом, при нужде, линии считывалась используя уже ранее понятные оффсеты. (Длина данной линии это просто разница между следующим и текущим оффсетом). Кодом могу поделиться, но он далеко (на старом компе в кладовке - доставать и грузить надо). На FASM'е - но алгоритм я уже описал.
ребята , решил перенести проект в юникодную версию и столкнулся с траблами, сразу говорю проект написан в Embarcader C++ Berlin и учел то что в настройках проекта надо сделать юникод, вот исходник Код (C++): struct FileMapping { HANDLE hFile; HANDLE hMapping; size_t fsize; wchar_t* dataPtr; }; void __fastcall TForm1::Button1Click(TObject *Sender) { HANDLE hHeap = HeapCreate(0,300,0); HANDLE hFile = CreateFile(L"E:\\strings.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); int sizeChars = GetFileSize(hFile, NULL); SECURITY_ATTRIBUTES secAttr; secAttr.lpSecurityDescriptor = NULL; secAttr.bInheritHandle = FALSE; HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);//nullptr wchar_t* lpText = NULL; lpText = (wchar_t*) MapViewOfFile(hFileMapping, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, sizeChars); BOOL loginOk = NULL; if(hHeap!=0 && lpText!=0) { wchar_t * lpString = NULL; lpString=(wchar_t*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,150); FileMapping* mapping = (FileMapping*)malloc(sizeof(FileMapping)); mapping->hFile = hFile; mapping->hMapping = hFileMapping; mapping->dataPtr = lpText; mapping->fsize = (size_t)sizeChars; for( ; mapping->dataPtr-2 != NULL ; mapping->dataPtr = mapping->dataPtr+wcslen(lpString)+4) { lpString = wcstok(mapping->dataPtr,L"\u000D\u000A"); if(lpString==NULL)break; MessgeBox(0, lpString, L"Alert", MB_OK); } mapping->dataPtr=lpText; HeapFree(hHeap, 0, lpString); UnmapViewOfFile(mapping->dataPtr); CloseHandle(mapping->hMapping); CloseHandle(mapping->hFile); free(mapping); } HANDLE hToken = NULL; } дело в том что он не ловит строки, пробовал дебагать но не фига не понял в листинге ольки и закрыл с перепуганным лицом... собственно выводит одно сообщение хотя в текстовом файле 3 строки, сообщение которое он выводит отображается иероглифами китайскими наверное...где-то я напортачил, помогите пожалуйста. Сразу оговорюсь что файл сохранен в кодировке юникод без БОМ вывод в блоке Edit = 瑓楲ㅮ匊牴ਲ呓卲牴ਲ਼ или MessageBox одинаково иероглифы
я таки своего добился выводит нормально но каждый раз перекодировать файл в Notepad++ в кодировку UCS-2 Little Endian както геморойно