powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
35 сообщений из 35, показаны все 2 страниц
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38695637
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
41 Белый Котик,

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


Ребятушки, осадите.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38696134
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury, Саш строго говоря такой код можно было писать лет 20 назад и то с оговорками.
В наше время ЛЮБАЯ задача обработки текстовых файлов вызывает главный вопрос. С какой
кодировкой будет файл. У нас собственно есть варианты: windows-1251 (1-байтная), cpp866 (1-байтная устаревшая),
unicode-16(UTF-16) (2-байтная), utf-8 (плавающая разрядность). Есть еще также редкие koi8-
и прочие от устаревших ЭВМ но существующие в виде интернет контента.

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

Все прочие попытки реализовать текстовое сравнение двух файлов как сравнение бинарей
(побайтно) - это профанация.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697094
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
c guy, отличный пример на С, я щитаю, лучший, имхо
P.S. сорри за оверквотинг выше, рука дрогнула
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697119
29 Белых Котиков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Второй файл называется f2.txt, а не f1.txt
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697127
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отступы, пробелы, табуляторы... Игнорируем?
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697454
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прочитал это и это .
Не до конца понял только одну фразу

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

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

У меня может идти английский текст вперемешку с русским, а если я ещё перемещаю с китайским, то я все символы буду хранить по 4 байта, или произойдёт разбиение на блоки ? Значит блок в котором хранится количество байт на один символ должен как-то маркироваться.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697463
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем задавать так много глупых вопросов, если UTF8 разжёван на каждом углу???
А в UTF16 единственный неочевидный момент - суррогатные пары.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697471
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697476
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, я очень сомневаюсь, что вопросы касаемо стандартов можно назвать глупыми. Возможно вы хотели сказать -"тех вопросов, ответы на которые можно или нужно найти самому", хотя я прочитал в нескольких источниках и ответа на этот вопрос не нашёл.
Можно называть глупыми людей, что не задают вопросов прочитав то или иное, или не ставит под сомнение то или иное. Или считающих глупыми вопросы несущие фундаментальных характер.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697485
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBasil A. Sidorov, я очень сомневаюсь, что вопросы касаемо стандартов можно назвать глупымиВаши вопросы касались не стандартов и даже не описания форматов, конкретных статей.
Так вот - глупо задавать такие вопросы, если и стандарт и описание (очень простого) формата гуглятся за пару минут: просто вбили "utf8" в поисковик и две первые ссылки будут на русскую и английскую статьи вики.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697760
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторУ меня может идти английский текст вперемешку с русским, а если я ещё перемещаю с китайским, то я все символы буду хранить по 4 байта, или произойдёт разбиение на блоки ? Значит блок в котором хранится количество байт на один символ должен как-то маркироваться.
Нет. В текстовом файле нет блоков. Каждый символ - сам по себе.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38697893
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: Отредактировано
utf8 - байтовая кодировка. В частности, она полностью совместима со стандартными строковыми функциями це-рантайма.

P.S. Юникод ограничен базовой плоскостью и шестнадцатью дополнительным, поэтому более четырех байт на кодовую точку в UTF8 строке никогда не будет.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38698562
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4. Не засчитывается последнее слово, если файл не заканчивается разделителем.
5. Не проверялась компилируемость
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #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
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38699869
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov 5. Не проверялась компилируемость

Так это вы про свой код! Я тут его пытался запустить
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38700812
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryА где в данном коде работа с символами ?В getc/putc.
Некорректными они будут только на кодировках со встроенными нулями (UTF-16/UTF-32) - всё остальное пережуёт побайтово.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38701483
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovSashaMercuryА где в данном коде работа с символами ?В getc/putc.
Некорректными они будут только на кодировках со встроенными нулями (UTF-16/UTF-32) - всё остальное пережуёт побайтово.

Ну у меня при работе с файлом и вывод текста на консоль были проблемы. Потому пришлось работать с локалью.

Но всё равно надо делать какой-нибудь фильтр. А вдруг у меня в файле идут английские, русский, китайские буквы разом. Получается, по-хорошему, надо 1-определить в какой кодировке каждая буква, 2 - установить локаль в эту кодировку, 3- вывести эту букву на поток вывод, и снова к шагу 1. Я правильно понимаю ?
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38701496
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот тут почему-то не происходит запись в файл ( Подскажите в чём дело пожалуйста. Не нашёл в сети ни одного нормального примера по замене прописных букв в строчные. Судя по работе этой функции, такое чувство что файл просто не сохраняется.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
int all_to_lowercase(char* file_location)
{
	FILE* f = fopen(file_location,"r+");
	if (f == NULL)
	{
		printf("Unable to open file \n");
		return -1;
	}
	int count = 0;
	int c;
	while (EOF != (c = getc(f)))
	{
		//isupper(c) ? ++count, putc('/b', f), putc(tolower(c), f),printf("%i",count) : false;
		if (isupper(c))
		{
			count++;
			printf("%i", count);
			putc(tolower(c), f);
		}
	}
	fclose(f);
	return count;
}
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38701499
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уже час разбираюсь, алгоритм элементарный, а как сделать не знаю. Не хочу перенаправлять поток в другой файл, хочу изменить в этом. Или вы в таких случаях перенаправили бы поток в другое место ?
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38701672
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38702277
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНо всё равно надо делать какой-нибудь фильтр. А вдруг у меня в файле идут английские, русский, китайские буквы разомРазом они могут оказаться только в юникоде.
Если привыкнуть, что единственный адекватный "транспортный вариант" кодировки юникода - UTF8, то никаких проблем не возникает, т.к. UTF8 - байтовая кодировка, а ваш код работает исключительно с US-ASCII.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38702281
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНе хочу перенаправлять поток в другой файл, хочу изменить в этом. Или вы в таких случаях перенаправили бы поток в другое место ?Нет (универсального) способа менять файл.
Есть, конечно, вариант "всосать в память, модифицировать и записать обратно", но:
1. Требуется много памяти. Иногда - недопустимо много;
2. Сбой в процессе записи приводит к неустранимому повреждению данных.
Каждое из этих соображений убедительно само по себе, но вместе они не оставляют выбора: используйте отдельный файл для записи результата, а работу с записями оставьте специально организованным системам.
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38702468
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте C: Всем спасибо за советы.

Basil A. SidorovSashaMercuryНе хочу перенаправлять поток в другой файл, хочу изменить в этом. Или вы в таких случаях перенаправили бы поток в другое место ?Нет (универсального) способа менять файл.
Есть, конечно, вариант "всосать в память, модифицировать и записать обратно", но:
1. Требуется много памяти. Иногда - недопустимо много;
2. Сбой в процессе записи приводит к неустранимому повреждению данных.
Каждое из этих соображений убедительно само по себе, но вместе они не оставляют выбора: используйте отдельный файл для записи результата, а работу с записями оставьте специально организованным системам.


Интересно, пожалуй я согласен. Но только мне казалось что мне необязательно всасывать весь файл в память выделенную для работы программы (думаю понятно что я говорю), думал что можно изменять файл онлайн, как я пробовал выше. С двумя потоками совсем просто, сделал ещё вчера

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
//Все строчные буквы преобразуются к прописным
int all_to_lowercase(const char* file_location_in, const char* file_location_out)
{
	FILE* in = fopen(file_location_in,"r");
	FILE* out = fopen(file_location_out, "r+");
	if (in == NULL || out == NULL)
	{
		printf("Unable to open files \n");
		return -1;
	}
	int count = 0;
	int c;
	while (EOF != (c = getc(in)))
	{
		isupper(c) ? ++count, putc(tolower(c), out) : putc(c,out);
	}
	fclose(in);
	fclose(out);
	return count;
}



А почему не работает этот код ?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
while (EOF != (c = getc(f)))
	{
		//isupper(c) ? ++count, putc('/b', f), putc(tolower(c), f),printf("%i",count) : false;
		if (isupper(c))
		{
			count++;
			printf("%i", count);
			putc(tolower(c), f);
		}
	}



Сейчас буду пробовать реализовать задуманное (изменение сразу в файле), всё равно нужно знать, даже если это не очень хорошо, с помощью предложенных функций
...
Рейтинг: 0 / 0
Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
    #38702713
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
А почему не работает этот код ?



условие if (isupper(c)) тут лишнее.
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Можно ли сделать код для сравнения двух файлов быстрее и красивее ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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