Porównanie dwóch różnych łańcuchów tekstowych

0

Witam.
mam sobie takie zmienne:

string zmienna1;  //tablica zmiennych typu string - bardzo mi potrzebna
char zmienna2[99]; //zmienna typy char

Oraz chciałbym te łańcuchy porównać względem siebie, tzn.:
Jeśli zmienna2 będzie się równać zmienna1 ma się wykonać zdefiniowana po if-ie czynność.
zmienna2 (albo wpisany ciąg znaków) będzie stała, zmienna1 (stąd użycie tablicy stringów) będzie zmienna[n-ty element pętli].

Próbuje coś z tym zrobić ale dawno nie miałem styczności z c++ i pozapominałem trochę :(

Pomoże ktoś z tym ?

2
strcmp(zmienna1.c_str(), zmienna2);
//Lub
zmienna1 == string(zmienna2);
2
if( zmienna1 == zmiena2) 
{
     // cos
} 
2

Zakładając, że w zmienna2 będzie ciąg znaków zakończony nullem, to najwygodniej będzie

if (zmienna1 == string(zmienna2))

Jeśli zmienna2 się nie zmienia, to można przed pętlą raz zdefiniować taki std::string

string str2(zmienna2);
for (...)
    if (zmienna1 == str2)
0

Dzięki za wasze odpowiedzi. Po powrocie do domu postaram się wypróbować wasze propozycje.

EDIT
Mam jeszcze pytanko troszkę odbiegające od tematu. Przy otwarciu pliku przy parametrach ios::in oraz ios::app. Plik się utworzy jeśli nie istnieje, a dane będą dopisywane na końcu pliku ??

0

Wszystko działa jak chcę poza jednym przypadkiem, a mianowicie. W operacji na plik jest licznik linii, który (jak łatwo można się domyślić) liczy każdą wczytaną linię. Nie dział mi jeden ważny aspekt, otóż kiedy porównywany tekst jest równy licznik ma dodawać linie, w innym przypadku ma nie działać (licznik ma pomijać daną linię). Próbowałem robić pusty else (wstawiam else, który nic nie robi), próbowałem także nic nie wpisywać poza if-em i także nic. Znaczy efekt jest taki, że nawet jak linia nie zawiera danego tekstu także nią liczy.

Mam jeszcze pytanie. Mam sobie coś takiego:

string DTBLE, TIME;
time_t rawtime;
struct tm* timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 80, "%Y%m%d%H%M%S", timeinfo);
string data(buffer);
string nowa;
DTBLE = data.substr(2, 6);
TIME = data.substr(8, 6);

Nie mogę przerobić tego na funkcję (zmiennych DTBLE i TIME używam w wielu miejscach aplikacji, a nie chce tego pisać w każdym potrzebnym miejscu). Może i głupie, ale nie wiem, jak zdefiniować funkcję, która będzie zwracać te dwie zmienne...

0
Kremius napisał(a):

Nie dział mi
Pokaż kod.

Może i głupie, ale nie wiem, jak zdefiniować funkcję, która będzie zwracać te dwie zmienne...

pair<string, string> foobar()
{
    ...
    return make_pair(DTBLE, TIME);
}
0

robię to za pomocą prostego IF'a

string str1[99];
int zmienna;

if(zmienna1[i]=="tekst"){
zmienna=zmienna+1;
}else{
//nic ma nie robić.
}

kod napisany z pamięci, gdyż nie mam chwilowo dostępu do pliku

A jak użyć tych zmiennych, tzn przy wywołaniu funkcji muszę podać je jako argumenty, np.:

//funkcja oczywiście wcześniej zdefiniowana

funkcja(DTBLE, TIME);

??

0

Nazwij zmienne sensownie, zmienna, zmienna1, zmienna2 nic nie mówią.
Co to jest zmienna1? Jeśli to jest std::string to powinno być:

if (zmienna1 == "tekst")
0

poniżej pełny kod

fstream plik("plik.txt", ios::in);
do {
  string line;
  int linie;
  getline(plik, line);
  string sprawdz;
  sprawdz = line.substr(0, 3);
  if (sprawdz = "010") {
    linie = linie + 1;
  }
} while (!plik.eof());
plik.close();

tak wygląda pełny kod

0

Samo porównanie wygląda ok, gdzie indziej skopałeś. Po czym wnioskujesz, że linie też się zwiększa, gdy nie ma tego pasującego tekstu?

A tu masz przykład użycia std::pair.

#include <iostream>
#include <utility>
#include <string>
using namespace std;

pair<string, string> foo()
{
	return make_pair("ala ma", " kaca");	
}

int main() 
{
	auto bar = foo();
	cout << "Pierwsze: " << bar.first << ", drugie: " << bar.second << endl;
	
	return 0;
}
0

Stąd iż końcowa wartość tej funkcji jest wypisywana do pliku tekstowego

P.S Jak robicie te "małe" odpowiedzi pod danym postem ??

0

Całego nie wrzucam, w main jest wywołanie funkcji, kom013, oraz kom030 (ich nie wrzucam, gdyż wielkością są podobne do kom010, a różnią się tylko wypisaną informacją):

 
#include <fstream>
#include <iostream>
#include <conio.h>
#include <string.h>
#include <utility>
#include <string>
#include <stdio.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <Windows.h>

using namespace std;

void wyswietl();
void menu(int typ);
void menu();
void kom010();
void kom013();
void kom030();
void sprawdz();
int typ;

int main() {
  wyswietl();
  switch (typ) {
    case 1: {
      system("cls");
      cout << "Komunikat 010\n";
      kom010();
      main();
      break;
    }

    case 2: {
      system("cls");
      cout << "Komunikat 013\n";
      kom013();
      main();
      break;
    }

    case 3: {
      system("cls");
      cout << "Komunikat 030\n";
      kom030();
      main();
      break;
    }

    case 0: {
      break;
    }

    default:
      main();
  }
}

void wyswietl() {
  HANDLE kolor;
  kolor = GetStdHandle(STD_OUTPUT_HANDLE);
  SetConsoleTextAttribute(kolor, 10);
  system("cls");
  cout << "Wybierz typ komunikatu:\n";
  cout << "1 -> 010\n";
  cout << "2 -> 013\n";
  cout << "3 -> 030\n";
  SetConsoleTextAttribute(kolor, 11);
  cout << "\n::";
  cin >> typ;
}

void kom010() {
  fstream plik("010.txt", ios::in);
  system("cls");

  string line;
  string TPITI[99], SEMOV[99], CDMAG[99], MODAM[99], TELAC[99], FIL10[99],
      CNTER[99], NRVEN[99], COLLO[99], CDCOL[99], DESC1[99], DTMER[99],
      VINNO[99], DADOC[99], NRFTF[99], CDVAL[99];
  string PREIM[99], FLCEE[99], ENGIN[99], LNPRD[99], CDFOA[99], SRCAR[99],
      PESLO[99], CDCLM[99], INSAM[99], FREAM[99], PESNE[99];
  string HEADER, HEADR, HDRTPITI, HDRNTRAS, HDRNRECO, HDRCDMAG, HDRMITTE,
      HDRDTTRX, HDRORTRX;
  string DTBLE, TIME;
  string UZUPEL;

  time_t rawtime;
  struct tm* timeinfo;
  char buffer[80];
  time(&rawtime);
  timeinfo = localtime(&rawtime);
  strftime(buffer, 80, "%Y%m%d%H%M%S", timeinfo);
  string data(buffer);
  string nowa;
  DTBLE = data.substr(2, 6);
  TIME = data.substr(8, 6);

  string nazwa;

  int rekordy = 0;
  int koniec = 0;
  int i = 0;
  int linie = 0;
  int ile = 0;
  int loop = 0;
  int licznik = 0;

  string Rekord[99];
  string wynik[99];
  string wynik2[99];

  do {
    string line;
    getline(plik, line);
    string sprawdz;
    sprawdz = line.substr(0, 3);
    if (sprawdz = "010") {
      linie = linie + 1;
    }
  } while (!plik.eof());
  plik.close();

  rekordy = linie - 1;

  fstream plik3("010.txt", ios::in);

  while (!plik3.eof()) {
    getline(plik3, HEADR);
    // cout<<"\n"<<HEADR<<"\n";
    HDRTPITI = HEADR.substr(3, 5);
    HDRNRECO = HEADR.substr(8, 5);
    HDRCDMAG = HEADR.substr(13, 2);
    HDRMITTE = HEADR.substr(15, 15);
    HDRDTTRX = HEADR.substr(30, 6);
    HDRORTRX = HEADR.substr(36, 6);

    nazwa = "CAT" + HDRTPITI + ".txt";

    for (int i = 0; i < rekordy; i++) {
      getline(plik3, Rekord[i]);
      // licznik=licznik+1;
      // cout<<Rekord[i]<<"\n";
      TPITI[i] = Rekord[i].substr(0, 3);
      SEMOV[i] = Rekord[i].substr(3, 1);
      CDMAG[i] = Rekord[i].substr(4, 2);
      MODAM[i] = Rekord[i].substr(6, 15);
      TELAC[i] = Rekord[i].substr(21, 6);
      FIL10[i] = Rekord[i].substr(27, 13);
      CNTER[i] = Rekord[i].substr(40, 12);
      NRVEN[i] = Rekord[i].substr(52, 10);
      COLLO[i] = Rekord[i].substr(62, 6);
      CDCOL[i] = Rekord[i].substr(68, 3);
      DESC1[i] = Rekord[i].substr(71, 15);
      DTMER[i] = DTBLE;
      VINNO[i] = Rekord[i].substr(92, 17);
      DADOC[i] = DTBLE;
      NRFTF[i] = Rekord[i].substr(115, 11);
      CDVAL[i] = Rekord[i].substr(126, 3);
      PREIM[i] = Rekord[i].substr(129, 11);
      FLCEE[i] = Rekord[i].substr(140, 1);
      ENGIN[i] = Rekord[i].substr(141, 18);
      LNPRD[i] = Rekord[i].substr(159, 1);
      CDFOA[i] = Rekord[i].substr(160, 6);
      SRCAR[i] = Rekord[i].substr(166, 1);
      PESLO[i] = Rekord[i].substr(167, 7);
      CDCLM[i] = Rekord[i].substr(174, 3);
      INSAM[i] = Rekord[i].substr(177, 17);
      FREAM[i] = Rekord[i].substr(194, 17);
      PESNE[i] = Rekord[i].substr(211, 7);
      wynik[i] = "040" + SEMOV[i] + CDMAG[i] + MODAM[i] + TELAC[i] + DTMER[i] +
                 "      " + DADOC[i] + VINNO[i] + LNPRD[i] + "      \n";
    }
    int licznik = rekordy;
    koniec = licznik + 1;
  }
  ile = (int)log10(koniec) + 1;
  loop = 5 - ile;

  const char* zapis = nazwa.c_str();

  fstream plik2(zapis, ios::out);
  plik2 << "HDR" << HDRTPITI << UZUPEL;
  for (int i = 0; i < loop; i++) {
    plik2 << "0";
  }
  plik2 << koniec << "  CAT2W          " << DTBLE << TIME << "\n";

  for (int i = 0; i < rekordy; i++) {
    // cout<<wynik[i];
    plik2 << wynik[i];
  }
}

chcę przerobić to tak, aby czas (funkcja pokazana wyżej) była w osobnej funkcji (którą się wywołuje), oraz zapis także był w innej funkcji (funkcja kom030 posiadazmienne string wynik[99], oraz string wynik2[99] a reszta posiada tylko jedną, co chciałbym w tym uwzględnić.

EDIT
Tą funkcje z pair normalnie się definiuje (chodzi mi o prototyp funkcji) ??

0
do
{
      getline(plik, line);
      linie=linie+1;
}

gdzie masz jakiekolwiek sprawdzenie?

0

sorry, wrzuciłem kod z przed dodania sprawdzenia, już poprawiam

1
Debuguj

Sprawdź jaką wartość ma linie po wyjściu z pętli

<code class="message">Sprawdź jaką wartość ma wczytana linia gdy wchodzisz do `if`a
0

Sprawdzenie poprawię później teraz dla mnie priorytetem jest zrobienie tego kodu bardziej przejrzystego...

Napisałem tą funkcję z tym pair. Muszę zrobić jej prototyp (jak w przypadku innych funkcji, czy jakoś inaczej )??

Zrobiłem funkcje odpowiadająca na wzór jak podałeś:

pair<string, string> czas() {
  string DTBLE, TIME;
  time_t rawtime;
  struct tm* timeinfo;
  char buffer[80];
  time(&rawtime);
  timeinfo = localtime(&rawtime);
  strftime(buffer, 80, "%Y%m%d%H%M%S", timeinfo);
  string data(buffer);
  string nowa;
  DTBLE = data.substr(2, 6);
  TIME = data.substr(8, 6);

  return make_pair(DTBLE, TIME);
}

a wypisać wartości próbowałem tak:

auto bar = czas();
cout << "Pierwsze: " << bar.first << ", drugie: " << bar.second << endl;

Wyskakuje mi błąd:
**bar does not name of type

0

Nie wiem jak to sprawdzić. Dałem coś takiego:

pair<string, string> bar = czas() //dodając średnik także jest błąd
{
 	string DTBLE,TIME;
	time_t rawtime;
    struct tm * timeinfo;
  	char buffer [80];	
  	time (&rawtime);
  	timeinfo = localtime (&rawtime);
  	strftime (buffer,80,"%Y%m%d%H%M%S",timeinfo);
  	string data(buffer);
  	string nowa;
  	DTBLE=data.substr(2,6);
  	TIME=data.substr(8,6);
  	
    return make_pair(DTBLE, TIME);
}

z powyższym dochodzi tylko bląd:
**'czas' was not declared in this scope

2

Sprawdza się za pomocą ==, a nie =

0

Zrobiłem z tym sprawdzenie (dobra uwaga, nie zauważyłem jednego =). Efekt jest taki, że liczy dobrze, ale na końcu w pliku końcowym zapisana jest zmienna, która uwzględnia ten rekord, którego ma nie liczyć (mimo, że dana linia nie jest wypisana w tym pliku). Nie wiem, dlaczego.

Co z tym pair ??

0
Kremius napisał(a):

Zrobiłem z tym sprawdzenie (dobra uwaga, nie zauważyłem jednego =). Efekt jest taki, że liczy dobrze, ale na końcu w pliku końcowym zapisana jest zmienna, która uwzględnia ten rekord, którego ma nie liczyć (mimo, że dana linia nie jest wypisana w tym pliku). Nie wiem, dlaczego.
Debuguj.

Co z tym pair ??
Przeczytałeś mój komentarz? Czy masz włączone C++11? Jak nie to nie możesz użyć auto i musisz

pair<string, string> bar = czas();

Jeśli nadal będzie jakiś błąd to podaj:

  1. Komunikat błędu
  2. Linię kodu, której ten błąd dotyczy
0

Mam taki oto fragment

char* wczytaj(){
	char* nazwa_pliku;
	cout<<"Plik: ";
	cin>>nazwa_pliku;
	
	return nazwa_pliku;
}

wywołanie tej funkcji wygląda tak:

wczytaj();

Jak wynik powyższej funkcji dać jako argument do innej funkcji, tak aby użyć go jako wczytywany plik ??

0

Mam jeszcze pytanie jak zrobić funkcję, która zwraca zmienną char (nazwa pliku), zdefiniowanie (oraz wczytanie) zmiennej wygląda następująco:

/*typ zmiennej*/ wyswietl() {
  cout << "Plik: ";
  cin >> odczyt;
}

Typ zmiennej nie wiem jaki ma być, więc wpisałem tak.

0

Ale czemu char* skoro jest do dyspozycji std::string?

 
string wczytajNazwePliku()
{
  string wczytanaNazwa;

  getline( wczytanaNazwa, cin );
  
  return wczytanaNazwa;
}
0

Przy wczytaniu nazwy pliku (dalej, przy użyciu getline) żąda ode mnie zmiennej char

0
char* nazwa_pliku;
cout<<"Plik: ";
cin>>nazwa_pliku;

Unikaj używania char* bo na razie nie rozumiesz, czym jest wskaźnik a czym tablica znaków. W tym kawałku kodu zadeklarowałeś wskaźnik, nie zaalokowałeś pamięci i próbowałeś wczytać jakiś tekst do miejsca, na który wskazuje ten wskaźnik. W najlepszym przypadku program się wysypie, w najgorszym będziesz przez tydzień szukać błędu.

0

Wskaźników nigdy nie ogarniałem, sorry za zamieszanie.
Użyłem funkcji podanej wyżej (dałem tylko swoje nazwy):

string wczytajPlik() {
  string odczyt;
  getline(odczyt, cin);

  return odczyt;
}

błąd mam następujący:
[Error] no matching function for call to 'getline(std::string&, std::istream&)'

1

Przy wczytaniu nazwy pliku (dalej, przy użyciu getline) żąda ode mnie zmiennej char

[Error] no matching function for call to 'getline(std::string&, std::istream&)'

Nie widzę, żeby gdzieś żądało char.

Mogę Ci dać rybkę (rozwiązanie), ale lepiej będzie jak się nauczysz korzystać z wędki (dokumentacji). Wejdź tu: http://www.cplusplus.com/reference/string/string/getline/?kw=getline i popatrz jakich parametrów i w jakiej kolejności oczekuje getline.

0

OK. Problem jest kolejny, próbuje, wrzucić te zmienną jako argument danej funkcji, a wyskakuje mi:

wczytajPlik();
kom030(odczyt);

a funkcja wygląda tak:

string wczytajPlik()
{
  string odczyt;
  getline(cin,odczyt);  //kolejność, że cin jest pierwsze znalazłem na stronie do której podałeś link
 
  return odczyt;
}
0
Kremius napisał(a):

OK. Problem jest kolejny, próbuje, wrzucić te zmienną jako argument danej funkcji, a wyskakuje mi:

wczytajPlik();
kom030(odczyt);

Wyskakuje Ci kod? To ciekawe...

Przecież odczyt to zmienna lokalna funkcji wczytajPlik(), dlaczego chcesz jej użyć poza nią? Powinieneś jeszcze raz przerobić materiał z funkcji.

kom030(wczytajPlik());

1 użytkowników online, w tym zalogowanych: 0, gości: 1