Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Можно ли сделать код для сравнения двух файлов быстрее и красивее ? / 25 сообщений из 35, страница 1 из 2
14.07.2014, 04:11
    #38695582
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Здравствуйте.
В книге прочитал про программу diff с ключом -w. Данная программа игнорирует различия версий файлов связанных с наличием отступов, пробелов и других пустых мест. Решил написать её сам, написал код, но мне не кажется что он самый оптимальный и красивый. Подскажите как его оптимизировать, пожалуйста.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
#include <stdio.h>


/*
	Comapre two files without spaces and line breaks
	return -2, if files not found or fopen gives NULL
	return -1, if file are not equivalents
	return 1, if if file are equivalents 
*/
int compare2f(char** address_file)
{
	FILE* f1 = fopen(*(address_file + 1), "r");
	FILE* f2 = fopen(*(address_file + 2), "r");
	if (f1 == NULL || f2 == NULL)
	{
		printf("File(s) not found \n");
		return -2;
	}
	else
	{
		int f1_c=getc(f1);
		int f2_c=getc(f2);
		while (f1_c!=-1)
		{
			if (f1_c == ' ' || f1_c == '\n')
			{
				f1_c = getc(f1);
				continue;//goto UPwhile
			}
			else if (f1_c == f2_c)
			{
				f1_c = getc(f1);
				f2_c = getc(f2);
				continue;//goto UPwhile
			}
			else
			{
				if (f2_c == ' ' || f2_c== '\n')
				{
					f2_c = getc(f2);
					continue;//goto UPwhile
				}
				else
				{
					printf("Files are not equivalents \n");
					return -1;
				}
			}
		}

		//check the end of the second file
		while ((f2_c = getc(f2)) != -1)
		{
			if (f2_c != ' ' && f2_c != '\n')
			{
				break;
			}
		}


		if (f2_c == -1)
		{
			printf("Files are equivalents \n");
			return 1;
		}
		else
		{
			printf("Files are not equivalents \n");
			return -1;
		}
	}
}


int main(int argc, char** argv)
{
	compare2f(argv);
	return 0;
}
...
Рейтинг: 0 / 0
14.07.2014, 06:53
    #38695593
41 Белый Котик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
1. Не используется константа EOF, что плохо
2. Не закрываются открытые файлы
3. Проверка результата и печать в одном месте. Получается слишком специализированная функция, заточенная под программу
4. Для проверки на пробельность есть функция isspace
5. else if (f1_c == f2_c) должно было быть впереди, так как непробельных символов в файлах больше, чем пробельных
6. Дубли кода "if (f2_c == ' ' || f2_c== '\n')" надо вынести в одно место, это проверки одного вида
7. Да и вообще, сравнивать два файла скучно Сравнивайте сразу много файлов

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
#include <stdio.h>
#include <stdlib.h>


/*
	Comapre two files without spaces and line breaks
	return -2, if files not found or fopen gives NULL
	return -1, if file are not equivalents
	return 1, if if file are equivalents 
*/
#define COMPAREQF_EQ   1
#define COMPAREQF_NE  -1
#define COMPAREQF_ER1 -2
#define COMPAREQF_ER2 -3
#define COMPAREQF_MIN_FILES_CNT 2
#define COMPAREQF_MAX_FILES_CNT 100
int compareqf(int files_cnt, char** fnamesv)
{
	FILE** f; /* file handlers */
        int* f_c; /* character buffers for compare */ 
	int i; /* loop iterator */

	int fin; /* loop exit trigger */
	int ne; /* files are not equal trigger */
	int nf; /* file not found trigger */

	if (files_cnt < COMPAREQF_MIN_FILES_CNT || files_cnt > COMPAREQF_MAX_FILES_CNT) {
		return COMPAREQF_ER2;
	}

	f = (FILE**)malloc(files_cnt*sizeof(FILE*));
	f_c = (int*)malloc(files_cnt*sizeof(int));
	
	fin=0;
	ne=0;
	nf=0;
	for (i=0; i<files_cnt; i++) {
		f[i]=fopen(fnamesv[i], "r");
		nf=nf||(NULL==f[i]);
	}
	fin=fin||nf;
	while (!fin && !ne) {
		for (i=0; i<files_cnt; i++) 
			while (isspace(f_c[i]=getc(f[i]))||(f_c[i]=='\n')); 

		for (i=0; i<files_cnt; i++) {
			fin=fin || (EOF==f_c[i]);
			ne=ne || (i>0 && (f_c[i]!=f_c[i-1]));
		}

	}
	for (i=0; i<files_cnt; i++) 
		if (f[i]) 
			fclose(f[i]);
	free((void*)f);
	free((void*)f_c);
	if (ne) {
		return COMPAREQF_NE;
	}
	if (nf) {
		return COMPAREQF_ER1;
	}
	return COMPAREQF_EQ;
}


int main(int argc, char** argv)
{
	switch(compareqf(argc-1, &argv[1])) {
		case COMPAREQF_EQ:
			printf("Files are equal each order\n");
			break;
		case COMPAREQF_NE:
			printf("Files are differs\n");
			break;
		case COMPAREQF_ER1:
			printf("Files not found\n");
			break;
		case COMPAREQF_ER2:
			printf("Invalid arguments\n");
			break;
	}
	return 0;
}

...
Рейтинг: 0 / 0
14.07.2014, 09:33
    #38695637
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
41 Белый Котик,

Код: plaintext
1.
f = (FILE**)malloc(files_cnt*sizeof(FILE*));


Ребятушки, осадите.
...
Рейтинг: 0 / 0
14.07.2014, 14:37
    #38695971
Strangecat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercury,

Напиши функцию int next_nonspace(FILE* f) которая возвращает следующий не isspace символ и радуйся:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
int compare2f(const char* fname1, const char* fname2)
{
   FILE* f1 = fopen(fname1, "r");
   FILE* f2 = fopen(fname2, "r");
   if (! f1 || ! f2) return -2;

   while(true){
        int a = next_nonspace(f1);
        int b = next_nonspace(f2);
        if (a != b) return -1;
        if (a == EOF) return 1;
        //b с EOF не надо сравнивать.  Если один файл закончился раньше, то a!=b вернёт -1
        //если оба закончатся на одинаковой позиции, то b = EOF тогда же, когда и a = EOF.
   }
}
...
Рейтинг: 0 / 0
14.07.2014, 17:36
    #38696134
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercury, Саш строго говоря такой код можно было писать лет 20 назад и то с оговорками.
В наше время ЛЮБАЯ задача обработки текстовых файлов вызывает главный вопрос. С какой
кодировкой будет файл. У нас собственно есть варианты: windows-1251 (1-байтная), cpp866 (1-байтная устаревшая),
unicode-16(UTF-16) (2-байтная), utf-8 (плавающая разрядность). Есть еще также редкие koi8-
и прочие от устаревших ЭВМ но существующие в виде интернет контента.

Поэтому твой софт должен содержать конвейер из двух фильтров для f1, f2 и выдавать на выходе
UNICODE-текст который ты будешь сравнивать по правилам текста.

Все прочие попытки реализовать текстовое сравнение двух файлов как сравнение бинарей
(побайтно) - это профанация.
...
Рейтинг: 0 / 0
15.07.2014, 01:26
    #38696464
c guy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercury,

самый короткий код - тот, что использует имеющиеся средства
вот пример только со стандарной библиотекой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include<algorithm>
#include<iterator>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
int main(int argc, char *argv[]) {
  assert(argc == 3);
  std::ifstream s1(argv[1]);
  std::ifstream s2(argv[2]);
  auto last = std::istream_iterator<std::string>();
  auto eq = std::mismatch( std::istream_iterator<std::string>(s1), last, std::istream_iterator<std::string>(s2) );
  std::cout << (eq.first == last && eq.second == last ? "match" : "nonmatch") << std::endl;
}



пример работы
Код: powershell
1.
2.
3.
4.
5.
$ g++ --std=c++0x c.cpp
$ ./a.out <(echo 1      2) <(echo 1 2) 
match
$ ./a.out <(echo 1      2) <(echo 1 2 3) 
nonmatch
...
Рейтинг: 0 / 0
15.07.2014, 16:59
    #38697090
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
c guySashaMercury,

самый короткий код - тот, что использует имеющиеся средства
вот пример только со стандарной библиотекой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include<algorithm>
#include<iterator>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
int main(int argc, char *argv[]) {
  assert(argc == 3);
  std::ifstream s1(argv[1]);
  std::ifstream s2(argv[2]);
  auto last = std::istream_iterator<std::string>();
  auto eq = std::mismatch( std::istream_iterator<std::string>(s1), last, std::istream_iterator<std::string>(s2) );
  std::cout << (eq.first == last && eq.second == last ? "match" : "nonmatch") << std::endl;
}

самый лучший пример на С, который я видел в своей жизни

пример работы
Код: powershell
1.
2.
3.
4.
5.
$ g++ --std=c++0x c.cpp
$ ./a.out <(echo 1      2) <(echo 1 2) 
match
$ ./a.out <(echo 1      2) <(echo 1 2 3) 
nonmatch
...
Рейтинг: 0 / 0
15.07.2014, 17:01
    #38697094
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
c guy, отличный пример на С, я щитаю, лучший, имхо
P.S. сорри за оверквотинг выше, рука дрогнула
...
Рейтинг: 0 / 0
15.07.2014, 17:29
    #38697117
29 Белых Котиков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Кстати, не работает.

f1.txt
Код: plaintext
1.
2.
3.
4.
5.
 1 -



 - -  



f1.txt
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
            1 -





-



Код: plaintext
1.
2.
test5.exe f1.txt f2.txt
match
...
Рейтинг: 0 / 0
15.07.2014, 17:30
    #38697119
29 Белых Котиков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Второй файл называется f2.txt, а не f1.txt
...
Рейтинг: 0 / 0
15.07.2014, 17:36
    #38697127
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Отступы, пробелы, табуляторы... Игнорируем?
...
Рейтинг: 0 / 0
16.07.2014, 01:59
    #38697333
c guy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
29 Белых Котиков,

да, как оказалось istream_iterator молча бежит за пределы, а mismatch не проверяет на выбегание второй из них, поэтому стандартный алгоритм выкидываем и пишем свой в 3 строчки:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include<iterator>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
template <class T> bool equal (T first1, T first2, T last) {
  for(; first1 != last && first2 != last; ++first1, ++first2 )
    if ( !(*first1 == *first2) ) return false;
  return first1 == last && first2 == last;
}
int main(int argc, char *argv[]) {
  assert(argc == 3);
  std::ifstream s1(argv[1]);
  std::ifstream s2(argv[2]);
  typedef std::istream_iterator<std::string> iter;
  std::cout << (equal(iter(s1), iter(s2), iter()) ? "match" : "nonmatch" ) << std::endl;
}
...
Рейтинг: 0 / 0
16.07.2014, 03:51
    #38697364
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Здравствуйте. Спасибо всем за ответы и примеры.

maytonSashaMercury, Саш строго говоря такой код можно было писать лет 20 назад и то с оговорками.
В наше время ЛЮБАЯ задача обработки текстовых файлов вызывает главный вопрос. С какой
кодировкой будет файл. У нас собственно есть варианты: windows-1251 (1-байтная), cpp866 (1-байтная устаревшая),
unicode-16(UTF-16) (2-байтная), utf-8 (плавающая разрядность). Есть еще также редкие koi8-
и прочие от устаревших ЭВМ но существующие в виде интернет контента.

Поэтому твой софт должен содержать конвейер из двух фильтров для f1, f2 и выдавать на выходе
UNICODE-текст который ты будешь сравнивать по правилам текста.

Все прочие попытки реализовать текстовое сравнение двух файлов как сравнение бинарей
(побайтно) - это профанация.


Да.. вы конечно смотрите дальше меня. Ибо я сегодня пытался написать функцию, для вывода каждого слова на новую строку в стандартный поток вывода, но вероятно возникли проблемы с кодировкой файла. Выводит то выводит, но не то. Это был первый вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
int print_one_word_per_line(FILE* f)
{
	int c;
	bool inword = false;
	bool nonewline = false;
	int count_words = 0;
	while ((c = getc(f)) != -1)
	{
		if (c != ' ' && c != '\n' && c != '\t' && c != '!' && c != '?' && c != '.' && c != ',')
		{
			if (inword == false)
			{
				inword = true;
				count_words++;
			}
			putc(c, stdout);
			//printf("%c", c);
			nonewline = true;
		}
		else
		{
			nonewline ? putc('\n', stdout), nonewline = false : false;
			inword = false;
		}
	}
	return count_words;
}



Тогда я решил написать так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
int print_one_word_per_line2(FILE* f)
{
	int c;
	bool inword = false;
	bool nonewline = false;
	int count_words = 0;

	char* cur_word = NULL;
	int cur_word_pow = 0;


	while ((c = getc(f)) != -1)
	{
		if (c != ' ' && c != '\n' && c != '\t' && c != '!' && c != '?' && c != '.' && c != ',')
		{
			cur_word_pow++;
			cur_word = (char*)realloc(cur_word, cur_word_pow);
			*(cur_word + cur_word_pow - 1) = c;
			if (inword == false)
			{
				inword == true;
				count_words++;
			}
			nonewline = true;
		}
		else
		{
			if (nonewline)
			{
				cur_word_pow++;
				cur_word = (char*)realloc(cur_word, cur_word_pow);
				*(cur_word + cur_word_pow - 1) = 0;

				printf("%s \n", cur_word);
				cur_word = NULL;//don't work free(cur_word)
				cur_word_pow = 0;
				nonewline = false;
			}
			inword = false;
		}
	}
	free(cur_word);
	return count_words;
}
}




Ну и как вы понимаете ничего не получилось. Сейчас почитаю про кодировки более подробно, вы были правы изначально.

egorych c guy, отличный пример на С, я щитаю, лучший, имхо
P.S. сорри за оверквотинг выше, рука дрогнула

а я только хотел сказать что это ведь не Си, потому этот код я разберу позже :)


Anatoly Moskovsky
Код: plaintext
1.
f = (FILE**)malloc(files_cnt*sizeof(FILE*));

Ребятушки, осадите


Неверно приведение к FILE** или к типу FILE нельзя применять SIZEOF() ?
...
Рейтинг: 0 / 0
16.07.2014, 08:56
    #38697454
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Прочитал это и это .
Не до конца понял только одну фразу

авторUTF-16 и UTF-8 являются кодировками с переменной длиной кодирования. Если символ может быть закодирован одним байтом(потому что номер пункта символа очень маленький), UTF-8 закодирует его одним байтом. Если нужно 2 байта, то используется 2 байта. Кодировка сообщает старшими битами, сколькими битами кодируется текущий символ. Такой способ экономит место, но так же и тратит его в случае, если эти сигнальные биты часто используются. UTF-16 является компромиссом: все символы как минимум двухбайтные, но их размер может увеличиваться до 4 байт, если нужно.

То есть существует спец символ в начале набора байта, как конец строки '\0',и в этом спецсимволе хранится размер того, сколько байт занимает один символ ?
Я могу прочитать это значение из файла txt ?

У меня может идти английский текст вперемешку с русским, а если я ещё перемещаю с китайским, то я все символы буду хранить по 4 байта, или произойдёт разбиение на блоки ? Значит блок в котором хранится количество байт на один символ должен как-то маркироваться.
...
Рейтинг: 0 / 0
16.07.2014, 09:05
    #38697463
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Зачем задавать так много глупых вопросов, если UTF8 разжёван на каждом углу???
А в UTF16 единственный неочевидный момент - суррогатные пары.
...
Рейтинг: 0 / 0
16.07.2014, 09:12
    #38697471
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
...
Рейтинг: 0 / 0
16.07.2014, 09:17
    #38697476
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Basil A. Sidorov, я очень сомневаюсь, что вопросы касаемо стандартов можно назвать глупыми. Возможно вы хотели сказать -"тех вопросов, ответы на которые можно или нужно найти самому", хотя я прочитал в нескольких источниках и ответа на этот вопрос не нашёл.
Можно называть глупыми людей, что не задают вопросов прочитав то или иное, или не ставит под сомнение то или иное. Или считающих глупыми вопросы несущие фундаментальных характер.
...
Рейтинг: 0 / 0
16.07.2014, 09:25
    #38697485
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercuryBasil A. Sidorov, я очень сомневаюсь, что вопросы касаемо стандартов можно назвать глупымиВаши вопросы касались не стандартов и даже не описания форматов, конкретных статей.
Так вот - глупо задавать такие вопросы, если и стандарт и описание (очень простого) формата гуглятся за пару минут: просто вбили "utf8" в поисковик и две первые ссылки будут на русскую и английскую статьи вики.
...
Рейтинг: 0 / 0
16.07.2014, 12:22
    #38697757
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercuryТо есть существует спец символ в начале набора байта, как конец строки '\0',и в этом спецсимволе хранится размер того, сколько байт занимает один символ ?
Я могу прочитать это значение из файла txt ?

По информации с Вики
Код: plaintext
1.
2.
3.
4.
5.
6.
(1 байт)  0aaa aaaa 
(2 байта) 110x xxxx 10xx xxxx
(3 байта) 1110 xxxx 10xx xxxx 10xx xxxx
(4 байта) 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
(5 байт)  1111 10xx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx
(6 байт)  1111 110x 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx


Я-бы пояснил это так. Кодировка Utf-8 использует "унарный код". Это код в котором количество подряд идущих
единичек интерпретируется как 1 разряд унарной системы. Разделителем конечно-же является нолик.

Здесь только исключением сделали шаблон "0*" Для диапазона [0..127] символов ASCII совпадает
с этим шаблоном поэтому utf-8 частично совместима с 1 байтной кодировкой.

Для национальных кодовых страниц будет шаблон "110*"
...
Рейтинг: 0 / 0
16.07.2014, 12:24
    #38697760
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
авторУ меня может идти английский текст вперемешку с русским, а если я ещё перемещаю с китайским, то я все символы буду хранить по 4 байта, или произойдёт разбиение на блоки ? Значит блок в котором хранится количество байт на один символ должен как-то маркироваться.
Нет. В текстовом файле нет блоков. Каждый символ - сам по себе.
...
Рейтинг: 0 / 0
16.07.2014, 13:51
    #38697893
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Модератор: Отредактировано
utf8 - байтовая кодировка. В частности, она полностью совместима со стандартными строковыми функциями це-рантайма.

P.S. Юникод ограничен базовой плоскостью и шестнадцатью дополнительным, поэтому более четырех байт на кодовую точку в UTF8 строке никогда не будет.
...
Рейтинг: 0 / 0
17.07.2014, 04:44
    #38698522
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
mayton, теперь понятно, спасибо. Не все конечно. Но понятно.

я сделал такую функцию
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
int print_one_word_per_line(FILE* f, const char* locale)
{
	setlocale(LC_ALL, locale);
	int c;
	bool inword = false;
	bool nonewline = false;
	int count_words = 0;
	while ((c = getc(f)) != -1)
	{
		if (c != ' ' && c != '\n' && c != '\t' && c != '!' && c != '?' && c != '.' && c != ',')
		{
			if (inword == false)
			{
				inword = true;
				count_words++;
			}
			putc(c, stdout);
			//printf("%c", c);
			nonewline = true;
		}
		else
		{
			nonewline ? putc('\n', stdout), nonewline = false : false;
			inword = false;
		}
	}
	setlocale(LC_ALL, "C");
	return count_words;
}



А вот ее вызов
Код: plaintext
1.
print_one_word_per_line(f,"Russian");



Но это порнография, ибо она не реентерабельна.
PS
Понял почему меня постоянно поправляли когда в сигнатуре функции я порой писал параметры без квалификатора const. Тем самым можно сразу показать что этот аргумент(с квалификатором const) меняться не будет, и передача значения по адресу происходит для другой цели, как в данном конкретном случае, fe.

Модератор: Отредактировано
...
Рейтинг: 0 / 0
17.07.2014, 08:41
    #38698560
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
SashaMercuryя сделал такую функциюНе очень, правда, понятно, зачем вам локаль, если вы её не используете и почему вас заботит работа этой функции в многопоточном окружении?
Особенно, с учётом того, что единственный разделяемый ресурс - стандартный поток вывода.
вариант
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
int wordSplit( FILE* f ) {
  int wordCount = 0;
  int ch;
  int flag = 1;
  while ( -1 != (ch = fgetc( f ) ) {
    switch ( c ) {
       ' ':
      '\t':
      '\n':
      '\r':
       '!':
       '?':
       '.':
       ',':
        if ( flag ) {
          putc( '\n', stdout;
          wordCount += 1;
        }
        flag = 0;
        break;
      default:
        flag = 1;
        putc( ch, stdout );
    }
  }
  return wordCount;
}

Дефекты (как минимум):
1. Засчитывается лишнее слово, если файл начинается с разделителя;
2. Принудительная конвертация сиволов конца строки в unix-вариант;
3. Не вполне обоснованный выбор списка разделителей и полное отсутствие анализа некоторых сочетаний.
...
Рейтинг: 0 / 0
17.07.2014, 08:46
    #38698562
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
4. Не засчитывается последнее слово, если файл не заканчивается разделителем.
5. Не проверялась компилируемость
...
Рейтинг: 0 / 0
18.07.2014, 07:27
    #38699868
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Basil A. Sidorov, я делал акцент на работу с кодировкой, то есть чтобы на поток вывода печаталась кириллица. Потому, вполне вероятно что алгоритм не идеален. Но код компилируется, всё нормально.

А где в данном коде работа с символами ? В случае если в файле будет кириллица, то вывод в stdout возможно будет некорректный.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
int wordSplit( FILE* f ) {
  int wordCount = 0;
  int ch;
  int flag = 1;
  while ( -1 != (ch = fgetc( f ) ) {
    switch ( c ) {
       ' ':
      '\t':
      '\n':
      '\r':
       '!':
       '?':
       '.':
       ',':
        if ( flag ) {
          putc( '\n', stdout;
          wordCount += 1;
        }
        flag = 0;
        break;
      default:
        flag = 1;
        putc( ch, stdout );
    }
  }
  return wordCount;
}
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Можно ли сделать код для сравнения двух файлов быстрее и красивее ? / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]