Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > сравнение строк txt файлов


Автор: disely 27.4.2008, 22:54
У меня есть 2-е кнопки. Под каждой из них я открываю файл txt. Использую VS 6, MFC. Нужно сравнить эти открытие файлы, а именно строчки. Если они одинаковы записать их в один файл, если строчки не повторялись, то записать их в др файл. 
Для создания объекта и открытия файла для чтения пишу
Код

........
CStdioFile File(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary);
.......

Подскажите плиз реализацию сравнения строк.
        

Автор: bronislav 27.4.2008, 23:17
Тебе на до найти строки из первого файла, которых нет во втором и строки, которые есть во втором?

Если так, то можно обойтись средствами STL

Код

strcmp(char*,char*);

Возвращает 0, если строки одинаковы

Автор: warmonger_ 28.4.2008, 00:19
Цитата(bronislav @ 27.4.2008,  22:17)
Если так, то можно обойтись средствами STL

Код

strcmp(char*,char*);


эта функция не имеет отношения к STL

Автор: xvr 28.4.2008, 10:21
Цитата(disely @ 27.4.2008,  22:54)
У меня есть 2-е кнопки. Под каждой из них я открываю файл txt. Использую VS 6, MFC. Нужно сравнить эти открытие файлы, а именно строчки. Если они одинаковы записать их в один файл, если строчки не повторялись, то записать их в др файл. 
Для создания объекта и открытия файла для чтения пишу
Код

........
CStdioFile File(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary);
.......

Подскажите плиз реализацию сравнения строк.

Используй stl. Читаешь строки из первого файла (все) в виде string и складывешь их в set. Потом читаешь строки из второго файла (по 1й штуке), проверяешь, есть ли она в set'е (set.count(str)!=0), в зависимости от результата, выводишь ее куда надо.

Автор: disely 28.4.2008, 11:45
а что такое stl, объясните пожалуйста smile 
я вот не знаю как считать все строки если я не знаю заранее количество тих строк
про strcmp я понял
Код

if (strcmp(buf1, buf2) == 0)
    MessageBox("совпадает!");
 else......

"xvr" изменяюсь за свою тупость, с этого места можна поподробней:
Цитата

...и складывешь их в set....есть ли она в set'е (set.count(str)!=0), 
    

Автор: xvr 28.4.2008, 20:39
Цитата(disely @ 28.4.2008,  11:45)
а что такое stl, объясните пожалуйста smile 

Библиотека такая, входит в стандарт языка С++ (в VS 6.0 имеется)
Цитата

я вот не знаю как считать все строки если я не знаю заранее количество тих строк
Читай подряд, пока файл не закончится

Цитата

"xvr" изменяюсь за свою тупость, с этого места можна поподробней:

Можно:
Код

set<CString> used_in_file_1;
CString str;

// Read whole file 1 (file1 is an CStdioFile)
while(file1.ReadString(str))
{
 used_in_file_1.insert(str);
}

// Read file 2 by line by line (file2 is CStdioFile)
while(file2.ReadString(str))
 if (used_in_file_1.count(str))
  {
    cout << "Duplicated string: " << (char*)str << endl;
  }
 else
  {
    cout << "Non duplicated string: " << (char*)str << endl;
  }

Автор: disely 29.4.2008, 21:43
 хорошо попробую, если что напишу.

Автор: xvr 30.4.2008, 07:51
Цитата(disely @ 29.4.2008,  21:43)
 хорошо попробую, если что напишу.

Не забудь сделать в начале файла
Код

#include <set>
using namespace std;

Автор: Veniamin 29.11.2012, 18:00
Есть файл, он содержит строку. Нужно сравнить с ним две имеющиеся строки, которая совпадает, вывести ответ.
Код

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <dos.h>

void main ()
{
  int i;
  char a[8]="Moscow", b[8]="London", c[8];
  FILE *f1;
  clrscr();
  f1=fopen("d:\\args","r");
  i=strcmp(a, fgets(c,8,f1));
  printf ("i=%d",i);
  if (i==0)
     printf ("\n Совпадает 1я строка"); 
  else if (i<0 || i>0)
    { i=strcmp(b, fgets(c,8,f1)); printf ("i=%d",i); 
     if (i==0)
       printf ("\n Совпадает 2я строка"); 
       else if (i<0 || i>0)
        printf ("\n Ни одна строка не равна "); 
    }
   fclose(f1);
}

Подскажите пожалуйста,  почему когда во 2й раз использую переменную i для сравнения, результат не равен 0 (строка файла совпадает со 2й имеющейся строкой) ?

Автор: baldina 29.11.2012, 18:30
потому что 2 раза fgets(c,8,f1);
второй раз считывается новая строка (а если в файле лишь одна строка, возвращается NULL)
Код

fgets(c,8,f1);
if (strcmp(a, c) == 0) {
 // совпадает 1я строка
} else if (strcmp(b, c) == 0) {
 // совпадает 2я строка
}

Автор: xvr 30.11.2012, 11:55
Кроме того, fgets вернет строку с завершающим '\n'. У вас ни в одной строке, с которой вы сравниваетесь, этого '\n' нет, так что ни одна строка не совпадет

Автор: baldina 30.11.2012, 12:06
если у него только одна строка, то совпадет

Автор: xvr 30.11.2012, 12:15
Цитата(baldina @  30.11.2012,  12:06 Найти цитируемый пост)
если у него только одна строка, то совпадет

Просто одной строки недостаточно, нужно еще что бы в конце ее не было перевода строки (некоторые редакторы могут этот самый перевод строки вообще сами влепить автоматически)

Автор: baldina 30.11.2012, 12:19
если есть перевод строки, это уже не одна строка))

Добавлено через 3 минуты и 45 секунд
ТС читает 8 символов (7 значащих), а сравнивает 6. 
поскольку число символов захардкодено, все наши измышления мимо))

Автор: Veniamin 30.11.2012, 15:14
baldinaC вашим кодом получилось, благодарю.

Автор: xvr 30.11.2012, 17:09
Цитата(baldina @  30.11.2012,  12:19 Найти цитируемый пост)
ТС читает 8 символов (7 значащих), а сравнивает 6. 
поскольку число символов захардкодено,

Где? У него вроде обычные strcmp стоят, без ограничений на размеры строк

Автор: baldina 30.11.2012, 23:35
Цитата(Veniamin @  29.11.2012,  18:00 Найти цитируемый пост)
char a[8]="Moscow", b[8]="London", c[8];

Цитата(Veniamin @  29.11.2012,  18:00 Найти цитируемый пост)
strcmp(a, fgets(c,8,f1))


Автор: tzirechnoy 1.12.2012, 12:52
Да, что только не делают люди лишь бы юникс не учить.

Автор: volatile 1.12.2012, 13:56
Цитата(tzirechnoy @  1.12.2012,  12:52 Найти цитируемый пост)
лишь бы юникс не учить. 

а что, если __выучить юникс__,  строки сравнивать уже не придется?

Автор: tzirechnoy 1.12.2012, 15:55
Если выучить юникс, то ответ на вопрос "как сравнить такие текстовые файлы" будет очевиден и не будет требовать двух страниц камментов.

Автор: baldina 1.12.2012, 17:02
tzirechnoy, что за манера высказывать мнение, не вникнув в суть вопроса

Автор: xvr 2.12.2012, 11:29
Цитата(baldina @ 30.11.2012,  23:35)
Цитата(Veniamin @  29.11.2012,  18:00 Найти цитируемый пост)
char a[8]="Moscow", b[8]="London", c[8];

Цитата(Veniamin @  29.11.2012,  18:00 Найти цитируемый пост)
strcmp(a, fgets(c,8,f1))

'Читает 8 символов' - вижу, а 'сравнивает 6' - нет.

Автор: baldina 3.12.2012, 10:24
я имел в виду "Moscow" и "London".

Автор: xvr 3.12.2012, 13:34
Цитата(baldina @ 3.12.2012,  10:24)
я имел в виду "Moscow" и "London".

Увы, strcmp будет сравнивать принимая во внимание длинну обоих входных строк. Так что "Moscow" не совпадет с "Moscow\n"  (равно как и London) smile 

Автор: baldina 3.12.2012, 14:51
обеих  smile 
но совпадет с "Moscow"
а мы вообще о чем? )))))))))))

Добавлено через 1 минуту и 27 секунд
ЗЫ: если в одной строке 6 + 0, то сравнение на этом и закончится независимо от длины второй

Автор: xvr 3.12.2012, 17:10
Цитата(baldina @  3.12.2012,  14:51 Найти цитируемый пост)
ЗЫ: если в одной строке 6 + 0, то сравнение на этом и закончится независимо от длины второй 

Неа. Сравнивать будет с учетом длинны обоих строк:
Код

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

int main()
{
 printf("%d\n",strcmp("Moscow","Moscow"));
 printf("%d\n",strcmp("Moscow","Moscow\n"));
}
Результат запуска -
Код

> ./a.out 
0
-1


Автор: baldina 3.12.2012, 18:43
xvr, сравнение заканчивается. когда заканчивается одна из строк. 
точнее - когда символы не равны или закончилась одна из строк (любая!)

в нашем случае (второе сравнение) оно заканчивается потому что '\0' != '\n'

поглядите например на такой цикл 
Код

do {
        c1 = *pStr1++;
        c2 = *pStr2++;
        v = c1 - c2;
} while ((v == 0) && (c1 != '\0'));

Автор: xvr 4.12.2012, 09:34
Цитата(baldina @  3.12.2012,  18:43 Найти цитируемый пост)
в нашем случае (второе сравнение) оно заканчивается потому что '\0' != '\n'

Да, заканчивается. Но strcmp при этом не считает, что строки равны - та строка, которая закончилась, будет считаться меньше, чем та, которая еще не закончилась.
Так что в сравнение попадет 7 символов (6 символов из строки образца и завершающий 0 в ней, и 6 символов из считанной из файла строки и символ '\n'). Так что сравниваться будет 7 символов, а не 6. А этого достаточно, что бы "Moscow" и "Moscow\n" не совпали

Цитата(baldina @  3.12.2012,  14:51 Найти цитируемый пост)
а мы вообще о чем? )))))))))))

Мы вот об этом -

Цитата(baldina @  30.11.2012,  12:19 Найти цитируемый пост)
ТС читает 8 символов (7 значащих), а сравнивает 6. 
поскольку число символов захардкодено, все наши измышления мимо)) 


Автор: baldina 4.12.2012, 18:03
Цитата(xvr @  4.12.2012,  09:34 Найти цитируемый пост)
А этого достаточно, что бы "Moscow" и "Moscow\n" не совпали

да я и не говорил что они совпадут
говорил, что в сравнении будут участвовать 6 (значащих) символов, т.к. такова длина захардкоденных строк
все это было, естественно, в предположении, что строка в файле одна и никакого \n нет

ну вобщем мы поняли кто чего хотел сказать)

Автор: xvr 5.12.2012, 13:05
Цитата(baldina @  4.12.2012,  18:03 Найти цитируемый пост)
ну вобщем мы поняли кто чего хотел сказать)

Угу, консенсус  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)