Войти

Показать полную графическую версию : Сортировка в файле


Страниц : [1] 2

DENoszone
09-07-2008, 11:39
Как осущесвялется сортировка в файлах и поиск.
пример.
ФАйла в одной строке одно слова.
Расортировать их по алфавиту и разбить на файлы по кол-ву букв.

mrcnn
09-07-2008, 13:51
Я хочу открыть файл и считать все содержимое
1. как это сделать построчно, используя WinAPI?
2. как это сделать считав весь файл сразу в какую-то переменную, используя WinAPI?

void main()
{
strng d="log.txt";
HANDLE hFile;
strng t;
DWORD cbreading;

DWORD fzi;

LPDWORD dwSizeHigh;
if (hFile=CreateFile(d,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL))
{


fzi = GetFileSize(hFile, NULL);
printf("%d", fzi); //OK - 304
ReadFile(hFile,&t,fzi,&cbreading,NULL); // как организовать цикл считывающий построчно?
printf("%s",&t); //глюк. если выше написать ReadFile(hFile,&t,100,&cbreading,NULL); то все ОК. Почему?

CloseHandle(hFile);
}
}

******Добавлено:

Ошибка была в том, что строка не инициализирована.
В общем файл читается полностью так.

#include <windows.h>
#include <stdio.h>

#define Msg(x) MessageBox(0,x,"program",MB_OK)

typedef char* strng;

strng create_string();
strng create_string(int sz);
void delete_string(strng m);
void print_string(strng t);
void terminate_string(strng m, int sz);

strng create_string(int sz)
{
strng m;
m = new char[sz+1];
terminate_string(m, sz+1);
return (m);
}

void delete_string(strng m)
{
delete[] m;
}


void print_string(strng t)
{
int i;
for (i=0;t[i]!='\0';i++)
{
printf("%C",t[i]);
}
printf("\n");
}

void terminate_string(strng m, int sz)
{
m[sz-1]='\0';
}


void main()
{
strng d="log.txt";
strng e="log1.txt";
HANDLE hFile, hCopy;
strng t;
DWORD cbreading;
DWORD fzi;
BOOL bResult;

if (hFile=CreateFile(d,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL))
{
fzi = GetFileSize(hFile, NULL);
t=create_string(fzi);
bResult = ReadFile(hFile, t, fzi, &cbreading, NULL);
if(!bResult) {

Msg("Невозможно прочитать файл!");
}
else
{
hCopy=CreateFile(e,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
NULL,
NULL);
WriteFile(hCopy, t, fzi, &cbreading, NULL);
CloseHandle(hCopy);
}
print_string(t);
delete_string(t);
CloseHandle(hFile);
}
}

DENoszone
09-07-2008, 18:31
WinAPI ? а чистое С но я смотрю они не сильно отличаются

mrcnn
09-07-2008, 19:28
На чистом С без WinAPI

#include <stdio.h>
int main()
{
FILE *in;
char* d="try.c";
if((in = fopen(d,"rt"))==NULL)
{
fprintf(stderr, "Не могу открыть файл \n");
}
while(!feof(in)){
fputc(fgetc(in), stdout);
}
fclose(in);
return(0);
}

Текст на каком языке и в какой кодировке?

Если текст на латинице, то буквы можно непосредственно сравнивать. ('a'>'b')
Если русский, то нужно сопоставить каждой букве числовой код.
Представить каждое слово в виде массива чисел. По порядку сравнивать элементы массива между собой пока точно не станет ясно, что начальные цифры одного меньше другого. и записывать в нужном порядке в новый массив.
Затем вернуть из чисел обратно в символьный вид. Как записывать в файл или читать из файла см. выше


Вместо new в чистом С используется функция malloc.

#include<stdio.h>
#include<string.h>
#include<alloc.h>
#include<process.h>

int main(void)
{
char *str;
/* выделить память под строку */
if((str = malloc(10)) == NULL)
{
printf("Недостаточно памяти\n");
exit(1); /* завершение с кодом ошибки */
}
/* скопировать в строку "Hello" */
strcpy(str,"Hello");
/* вывести строку */
printf("Строка: %s\n",str);
/* освободить память */
free(str);
return 0;
}

DENoszone
09-07-2008, 19:36
на русском.
блин...это ужас...это только подготовка к одному алгоритму....

кстати сюда сразу. мне надо осуществить ввод пароля...что бы при вводе выводились ****

mrcnn
09-07-2008, 20:33
[q]кстати сюда сразу. мне надо осуществить ввод пароля...что бы при вводе выводились ****[q]

#include <conio.h>
void main()
{
char buffer[5];
int i, ch;

for (i = 0; (i < 2) && ((ch = getch()) != EOF)
&& (ch != '\n'); i++)
{
buffer[i] = (char) ch;
printf("*");
}
printf("\n");
buffer[i] = '\0';
printf( "Input was: %s\n", buffer);
}

DENoszone
09-07-2008, 20:35
вау...огромное спасибо...
даже не думал что так можно for записать=) мега респект..а есть книжки с такими приколами?=)

mrcnn
09-07-2008, 20:43
гм. это не мой код.. :) это код из описания функции getc в MSDN, правда там чтение идет из файла.

DENoszone
10-07-2008, 15:13
не могу понять уже сколько читаю...
мне надо проитать 10 строчку.
или как проситать 10 строчку и 3 символ в файле ?

mrcnn
10-07-2008, 16:06
Перенос строки в текстовых файлах осуществляется
либо последовательностью \x0d\x0a
либо \x0a

См. # 2 в этой теме
Посимвольно просматриваешь t в цикле и сравниваешь с \x0a (if (t[i]=='\x0a') ;. Если встретили значит произошел перенос строки. Чтобы точно убедиться в переносе считываем и проверяем предыдущий символ if (t[i-1]=='\x0d') Если это \x0d то у нас совершенно точно перенос строки и мы увеличиваем счетчик строк.Чтобы пометить что мы в 10 строке, можно завести булевую переменную и присвоить ей значение 1. При старте инициализируем ее нулем. Обнуляем переменную cnt2 и продолжаем считывать символы. Если
bool==1 && cnt2==3 то у нас 3 символ 10 строки


counter=0;
booll=0;
....
for (int i=0;i<N;i++)
{
if (t[i]=='\x0a')
if (t[i-1]=='\x0d')
counter++,cnt2=-1;
if (counter==10)
{
booll=1; //10 строка
cnt2++;
}

if (booll==1 && cnt2==3)
{3 символ 10 строки}

....
}

Drongo
10-07-2008, 16:30
mrcnn, Вроде bool пишется с одной l, а не с двумя. :tomato2:

mrcnn
10-07-2008, 17:28
booll это имя переменной, а именам переменных нельзя присваивать названия ключевых слов, поэтому я добавил в конец еще одну l

DENoszone
10-07-2008, 22:56
\x0d\x0a - это что такое я такое даже не изучал???
это какой язык?=0

Drongo
10-07-2008, 23:22
mrcnn, booll это имя переменной »Не пойму, если bool boll;объявляет переменную типа bool, а в коде нет этого, объясни. :dont-know

mrcnn
11-07-2008, 07:58
В C нет типа bool. Булевую переменную объявляем как int или unsigned int.
В windef.h даже так и объявлено
typedef int BOOL;

В С++ тип bool есть.

Таким образом булевая переменная в C объявляется как
int booll
В С++ можно объявить булевую переменную
bool booll;
но компилятор выдаст ошибку, если ты попытаешься объявить переменную так:
bool bool;
bool int;
bool double;
bool float;

Литералы в С есть
1. в десятичной системе счисления 1,2,3
2. в восьмееричной системе счисления 01,02,03
3. в шестнадцатеричной системе счисления x1,x2,x3

Управляющие последовательности записываются с помощью символа \
Например \n \ t \r

Если мы хотим в тексте написать шестнадцатеричное число, то мы его записываем с помощью управляющей последовательности \xЧИСЛО
Например: \x1, \xa, \xf

DENoszone
11-07-2008, 11:21
Так не чего и не понял...или у меня высасали мозг...или =))))

Можно ещё раз полный код только С ну и начало С++
Поиск в тексте (текст 1 слово одна строчка)
1. Найти слово.
2. Найти в 10 срочке 3 символ
3. Найти все слова которые начинаются на "А"
4. Найти все слова которые заканчиваются на "Б"

И если не сложно то с обьяснениями, а тореально не могу вьехать...а хочу мозг прописать дял компа =)

mrcnn
11-07-2008, 15:27
Так не чего и не понял...или у меня высасали мозг...или )))

Можно ещё раз полный код только С ну и начало С++
Поиск в тексте (текст 1 слово одна строчка)
1. Найти слово.
2. Найти в 10 срочке 3 символ
3. Найти все слова которые начинаются на "А"
4. Найти все слова которые заканчиваются на "Б"

И если не сложно то с обьяснениями, а тореально не могу вьехать...а хочу мозг прописать дял компа



#include <windows.h>
#include <stdio.h>
#define Msg(x) MessageBox(0,x,"program",MB_OK)


typedef char* strng;

strng create_string();
strng create_string(int sz);
void delete_string(strng m);
void print_string(strng t);
int len_string(strng m);
strng rus_string_to_console(strng m);
char get_string_symbol(strng m,int nm);
void set_string_symbol(strng m, char s,int nm);
void terminate_string(strng m, int sz);
strng concatenate_string(strng m,strng n);
void copy_string(strng m,strng n);
int check_eng_symbol(char m);
int check_rus_symbol(char m);
int find(strng,int,int,int);
void find_word(strng t,int ls, strng slovo);
void find_sym(strng t,int ls, char sg);

strng create_string()
{
strng m;
m = new char[];
return (m);
}

strng create_string(int sz)
{
strng m;
m = new char[sz+1];
terminate_string(m, sz+1);
return (m);
}

void delete_string(strng m)
{
delete[] m;
}

void print_string(strng t)
{
int i;
for (i=0;t[i]!='\0';i++)
{
printf("%c",t[i]);
}
}

int len_string(strng m)
{
int i=0;

while (m[i] != '\0')
++i;
return i;
}


strng rus_string_to_console(strng m)
{
strng szBuffer;
int ln1=len_string(m);
szBuffer=create_string(ln1);
CharToOem(m, szBuffer);
return(szBuffer);
}

char get_string_symbol(strng m,int nm)
{
return (m[nm]);
}

void set_string_symbol(strng m, char s,int nm)
{
m[nm]=s;
}

void terminate_string(strng m, int sz)
{
m[sz-1]='\0';
}

strng concatenate_string(strng m,strng n)
{
strng szBuffer;
int ln,i,r,ln1,ln2;
ln1=len_string(m);
ln2=len_string(n);
ln=ln1+ln2;
szBuffer=create_string(ln);
r=0;
for (i=0;i<ln1;i++)
{
set_string_symbol(szBuffer, m[i],r);
r++;
}
for (i=0;i<ln2;i++)
{
set_string_symbol(szBuffer, n[i],r);
r++;
}
terminate_string(szBuffer,ln+1);
return szBuffer;
}

void copy_string(strng m,strng n)
{
int ln1,i;
ln1=len_string(m);
for (i=0;i<ln1;i++)
{
set_string_symbol(n, m[i],i);
}
terminate_string(n, ln1+1);
}

void main()
{
strng d="hash5.cpp"; // ФАЙЛ в котором ищем
HANDLE hFile;
strng t;
DWORD cbreading;
DWORD fzi;
BOOL bResult;

strng slovo="return";

if (hFile=CreateFile(d,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL))
{
fzi = GetFileSize(hFile, NULL);
t=create_string(fzi);
bResult = ReadFile(hFile, t, fzi, &cbreading, NULL);
if(!bResult) {

Msg("Невозможно прочитать файл!");
}
else
{
find(t, (int)fzi, 10,3); // 2. Найти в 10 строчке 3 символ
find_word(t,(int)fzi, slovo); //1. Найти слово.
find_sym(t, (int)fzi, 'r');
find_sym(t, (int)fzi, '\xc0'); //3. Найти все слова которые начинаются на "А"
find_sym(t, (int)fzi, '\xc1');//4. Найти все слова которые заканчиваются на "Б"
}
delete_string(t);
CloseHandle(hFile);
}
}

// 2. Найти в 10 строчке 3 символ
int find(strng t,int ls, int str,int numsym)
{
// t- строка в которой ищем А
// str - в какой строчке ищем Б
// numsym - какой символ ищем
int i,cnt2,counter,booll;
strng k;
strng l;

counter=1;
booll=0;
cnt2=-1;

for (i=0;i < ls;i++)
{

/* Поиск N символа в строке*/
if (t[i]=='\x0a')
{
if (t[i-1]=='\x0d')
{
counter++; //Увеличиваем счетчик строк
cnt2=-1; // счетчик символов
if (counter==str)
{
booll=1; // Мы в str строке
}
else
{
booll=0; // Мы не в str строке
}
}
}
cnt2++; // увеличиваем счетчик символов
if (cnt2==numsym) // Если numsym символ
{
if (booll==1) // Если str строка
{
printf("%d",numsym);
k="\x20символ в\x20";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf("%d",counter);
k="\x20строчке:\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf("\t%C\n",t[i]);
return(1);
}
}
}
return(0);

}

//1. Найти слово.
void find_word(strng t,int ls, strng s)
{
int i,pos,counter;
strng k;
strng l;

pos=0;
counter=1;
for (i=0;i<len_string(s);i++)
printf("%C",s[i]);
printf("\n");

for (i=0;i < ls;i++)
{
if (t[i]=='\x0a')
{
if (t[i-1]=='\x0d')
{
counter++; //Увеличиваем счетчик строк
}
}
if (t[i]==s[pos])
{
pos++;
if (pos==len_string(s))
{
k="Искомое слово\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
print_string(s);
k="\x20найдено в\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf ("%d",counter);
k="\x20строчке\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf("\n");
}
}
if (pos > 0 && t[i]!=s[pos-1])
{
pos=0;
}
}
}

//3. Найти все слова которые начинаются на "А"
void find_sym(strng t,int ls, char sg)
{

int i,j,nach_sl,kon_sl,insl,counter;
strng k;
strng l;

counter=1;
insl=0;

for (i=0;i < ls;i++)
{
if (t[i]=='\x0a')
{
if (t[i-1]=='\x0d')
{
counter++; //Увеличиваем счетчик строк
}
}
if (t[i]==sg && (t[i-1]=='\t' ||t[i-1]=='\x0a' ||t[i-1]=='\x20'||t[i-1]=='\n' ))
{
insl = 1;
nach_sl = i;
}
if (check_rus_symbol(sg))
{
if (insl == 1 && ! ( check_rus_symbol(t[i]) ) )
{
kon_sl = i;
insl = 0;
k="Cлово начинающееся с символа\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf ("\x20%C :\x20",sg);
for (j=nach_sl; j<kon_sl;j++)
{
printf ("%C",t[j]);
}
k="\x20в строке\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf ("%d\n",counter);
}
}
else if (check_eng_symbol(sg))
{
if (insl == 1 && ! ( check_eng_symbol(t[i]) ) )
{
kon_sl = i;
insl = 0;
k="Cлово начинающееся с символа\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf ("\x20%C :\x20",sg);
for (j=nach_sl; j<kon_sl;j++)
{
printf ("%C",t[j]);
}
k="\x20в строке\x20\0";
l=rus_string_to_console(k);
print_string(l);
delete_string(l);
printf ("%d\n",counter);
}
}
}
}

//Принадлежит ли символ английскому алфавиту
int check_eng_symbol(char m)
{
if ( (m>='\x41' && m<='\x5a') || (m>='\x61' && m<='\x7a') )
return (1);
else
return (0);
}

//Принадлежит ли символ русскому алфавиту в кодировке windows
int check_rus_symbol(char m)
{
if ( (m>='\xc0' && m<='\xdf') || (m>='\xe0' && m<='\xff') )
return (1);
else
return (0);
}

DENoszone
11-07-2008, 23:12
strng create_string(); - это что я с этим ещё не сталкивался.

mrcnn
12-07-2008, 15:31
С чем ты еще не сталкивался?

strng create_string(); это объявление функции, не имеющей параметров и возвращающей значение типа strng. Кода функции нет, программа должна искать его в другом месте, например ниже в тексте этого файла, в других cpp файлах, в lib файлах и т.д.

В общем случае функции объявляются следующим образом:
[тип_возвращаемого_значения] имя_функции (список_параметров)

Объявление функции возможно:
1. непосредственно в файле с кодом, т.е в файлах .c/.cpp
2. в заголовочных файлах т.е в файлах .h

strng create_string(); Это один из вариантов перегружаемой функции.
Перегрузкой называется объявление функций с одним и тем же именем, но разным списком аргументов.

В своих программах я придерживаюсь следующего порядка:

заголовочные файлы и макросы
список функций
глобальные переменные
main() или WinMain()
код функций

При таком порядке заголовочные файлы, макросы и список функций можно безболезненно перенести в .h файл, а сам код функций вынести в отдельный .c/.cpp файл.

Можно создать свое имя для какого-то типа данных, отражающее его сущность с помощью ключевого слова typedef
typedef char* strng
typedef базовый_тип_данных пользовательский_тип_данных
strng create_string(); эквивалентно char* create_string();

Это нужно, чтобы функция продолжала оставаться рабочей даже если мы переопределили тип по другому, т.е например написали
typedef int* strng
В моей программе переопределить так тип не получится, нужна проверка в функциях на соответствие данных. В общем случае лучше в каждой функции проверять соответствие параметров нужным - это сильно упрощает последующее использование кода в каких-либо других проектах.

DENoszone
14-07-2008, 13:19
Только сейчас смог запустить код
и сразу ошибки
Error 1 error C2664: 'CharToOemW' : cannot convert parameter 1 from 'strng' to 'LPCWSTR' c:\documents and settings\dudaev\мои документы\visual studio 2005\projects\балда\балда\балда.cpp 216
Error 2 error C2664: 'CreateFileW' : cannot convert parameter 1 from 'strng' to 'LPCWSTR' c:\documents and settings\dudaev\мои документы\visual studio 2005\projects\балда\балда\балда.cpp 286
Error 3 error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [27]' to 'LPCWSTR' c:\documents and settings\dudaev\мои документы\visual studio 2005\projects\балда\балда\балда.cpp 293

и find это разве С ?
hFile=CreateFile(d,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)
вот это как понять?
strng - это какой тип? я такого не изучал.

и как можно понять такую запись !bResult




© OSzone.net 2001-2012