Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kopiowanie zmiennych typu string

Ostatnio zmodyfikowano 2017-06-23 16:00
Autor Wiadomość
wisnia633
Temat założony przez niniejszego użytkownika
Kopiowanie zmiennych typu string
» 2017-06-16 11:05:05
Witam, jestem początkującym programista i trafiłem na problem z którym zmagam się od jakiegoś czasu. Mianowicie próbuję rozwiązać sposób kopiowania zmiennych typu string przy tworzonym programie postprocesora dla przerobienia pliku gcode na plik z samym zbiorem wartości punktów.Efekt jest taki że w miejscu gdzie wstawiam dane ze znalezionej wartości zmiennej Z dostaje dziwne znaki, nie wiem z czego to wynika. Dodatkowo nie mogę ustawić przesunięcia tej wstawianych przy użyciu funkij insert.

C/C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

string kopiowanie( string wiersz_konwert )
{
    char szukanyZnakZ = 'Z';
    char szukanyZnakY = 'Y';
    char wartoscZmiennejZ[ 6 ];
    int foundZ = wiersz_konwert.find( szukanyZnakZ );
   
    if( foundZ != string::npos )
    {
        size_t liczbaZnakaow = wiersz_konwert.copy( wartoscZmiennejZ, 6, foundZ + 1 );
        wartoscZmiennejZ[ liczbaZnakaow ] = '\0';
    }
   
    int foundY = wiersz_konwert.find( szukanyZnakY );
    if( foundY != string::npos )
    {
        wiersz_konwert.insert( foundY, wartoscZmiennejZ );
    }
    return wiersz_konwert;
}


int main()
{
    string nazwa_pliku; //deklarazja nazwy pliku wprowadzanej z klawiatury
   
    cout << "Podaj nazwe pliku: " << endl; //pytanie o nazwê pliku
    cin >> nazwa_pliku; //odczyt nazwy z klawiatury
   
    ifstream plik( nazwa_pliku.c_str(), ios::in ); //rozpoczêcie odczytu z pliku o podanej przez uzutkowanika nazwie
    ofstream nowy( "punkty.txt", ios::out | ios::app ); //stworzenei nowego pliku w którym zostana zapisane odczytywane dane
    if( plik.good() == true ) //sprawdzenie istnienia pliku
    {
        int nr_wiersza_odczyt = 0;
        //zmienna pomocnicza okreslajaca liczbe wierszy odczytanych
        while( !plik.eof() ) //petla dziala do wyczerpania wszystkich wierszy w pliku
        {
            string wiersz_odczyt;
            getline( plik, wiersz_odczyt ); //odczytanie z pliku zmiennej
           
            kopiowanie( wiersz_odczyt );
           
            cout << kopiowanie( wiersz_odczyt ) << endl;
            nowy << kopiowanie( wiersz_odczyt ) << endl; //zapis do pliku nowy
            nr_wiersza_odczyt++; //przejscie do nastepnego wiersza
           
        }
        cout << nr_wiersza_odczyt << endl;
       
    }
    else cout << "ERROR\n\n";
   
    plik.close();
    nowy.close();
}

To efekt działania programu:

G1 X149.505 NtżEY113.865 E9.3758 F600
G1 X149.505 NtżEY86.250 E10.7535
G1 X152.946 NtżEY86.250 E10.9251
G1 X152.946 NtżEY113.865 E12.3028
G1 X156.387 NtżEY113.865 E12.4745
G1 X156.387 NtżEY86.250 E13.8522
G1 X159.828 NtżEY86.250 E14.0239
G1 X159.828 NtżEY113.865 E15.4016
G1 X163.269 NtżEY113.865 E15.5732
G1 X163.269 NtżEY86.250 E16.9509
G1 X166.710 NtżEY86.250 E17.1226
G1 X166.710 NtżEY113.865 E18.5003
G1 X170.151 NtżEY113.865 E18.6720
G1 X170.151 NtżEY86.250 E20.0497
G1 X173.592 NtżEY88.313 E20.2498
G1 X173.592 NtżEY111.802 E21.4217
P-162589
karambaHZP
» 2017-06-16 11:14:39
Używasz operatora przypisania zamiast operatora porównania w instrukcji warunkowej.
Metoda find zwraca wartość typu std::size_t, o czym powinien ostrzec kompilator (zwiększ poziom ostrzeżeń).

Dalej nie czytałem. Otaguj kod.
P-162590
pekfos
» 2017-06-16 18:50:07
Po co ta tablica wartoscZmiennejZ? W twoim kodzie może być użyta niezainicjalizowana, a jak nawet ją wypełniasz danymi to potencjalnie przekraczasz jej zakres. Zamiast copy użyj substr i trzymaj się stringów.

C/C++
kopiowanie( wiersz_odczyt );

cout << kopiowanie( wiersz_odczyt ) << endl;
nowy << kopiowanie( wiersz_odczyt ) << endl;
Po co używasz tej funkcji 3 razy..?
P-162597
wisnia633
Temat założony przez niniejszego użytkownika
» 2017-06-16 21:09:04
Dzięki za zainteresowanie.

Poprawiłem kod , i trafiłem na kolejne problemy stosują operatory porównania. Jeśli dobre zrozumiałem w warunku if zamiast!= powinienem zastosować operator ==. Powoduje to problem z przekroczeniem
maksymalnej długości zmiennej string. Co do użycia funkcji 3 razy nie mam nic na swoją obronę.Ten sam log dostaje przy zmianie szukanych Z , Y z char na string.
 

C/C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

string kopiowanie( string wiersz_konwert )
{
    char szukanyZnakZ = 'Z';
    char szukanyZnakY = 'Y';
    string wartoscZmiennejZ;
   
    size_t foundZ = wiersz_konwert.find( szukanyZnakZ );
   
    if( foundZ == string::npos )
    {
        string wartoscZmiennejZ = wiersz_konwert.substr( foundZ, 6 );
    }
   
    size_t foundY = wiersz_konwert.find( szukanyZnakY );
   
    if( foundY == string::npos )
    {
        wiersz_konwert.insert( foundY, wartoscZmiennejZ );
    }
   
   
    return wiersz_konwert;
}


int main()
{
    string nazwa_pliku; //deklarazja nazwy pliku wprowadzanej z klawiatury
   
    cout << "Podaj nazwe pliku: " << endl; //pytanie o nazwê pliku
    cin >> nazwa_pliku; //odczyt nazwy z klawiatury
   
    ifstream plik( nazwa_pliku.c_str(), ios::in ); //rozpoczêcie odczytu z pliku o podanej przez u¿utkowanika nazwie
    ofstream nowy( "punkty.txt", ios::out | ios::app ); //stworzenei nowego pliku w którym zostana zapisane odczytywane dane
    if( plik.good() == true ) //sprawdzenie istnienia pliku
    {
        int nr_wiersza_odczyt = 0;
        //zmienna pomocnicza okreslajaca liczbe wierszy odczytanych
        while( !plik.eof() ) //petla dziala do wyczerpania wszystkich wierszy w pliku
        {
            string wiersz_odczyt;
            getline( plik, wiersz_odczyt ); //odczytanie z pliku zmiennej
           
            kopiowanie( wiersz_odczyt );
           
            nowy << kopiowanie( wiersz_odczyt ) << endl; //zapis do pliku nowy
            nr_wiersza_odczyt++; //przejscie do nastepnego wiersza
           
        }
        cout << nr_wiersza_odczyt << endl;
       
    }
    else cout << "ERROR\n\n";
   
    plik.close();
    nowy.close();
}


Podaj nazwe pliku:
20.gcode
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 4294967295) > this->size() (which is 30)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Process returned 3 (0x3)   execution time : 5.685 s
Press any key to continue.
P-162603
carlosmay
» 2017-06-16 21:58:45
» Kurs C++ » Poziom 1Operacje porównania lekcja
Jeśli dobre zrozumiałem w warunku if zamiast!= powinienem zastosować operator ==.
Oba są operatorami porównania.
Operatorem przypisania jest
=
.
P-162607
pekfos
» 2017-06-16 22:05:03
C/C++
if( foundZ == string::npos )
{
    string wartoscZmiennejZ = wiersz_konwert.substr( foundZ, 6 );
}
Powinno być !=, a ta zmienna w środku nic nie robi.
P-162609
wisnia633
Temat założony przez niniejszego użytkownika
» 2017-06-17 20:51:29
pekfos dzięki za rady bardzo pomogły.

Dotarłem do momentu w którym mogę skopiować cześć stringa ale okazuje się że funkcja kopiuje przy każdym wierszu 6 znaków i wkleja je w miejsce.
Obecnie głowie się dlaczego kod nie kopiuje wartości za Z 0.300 i nie wstawia w zadanym miejscu. Obecne efekty widać na logu poniżej.

C/C++
string kopiowanie( string wiersz_konwert )
{
    char szukanyZnakZ = 'Z';
    char szukanyZnakE = 'E';
    string wartoscZmiennejZ;
   
    size_t foundZ = wiersz_konwert.find( szukanyZnakZ );
   
    wartoscZmiennejZ = wiersz_konwert.substr( foundZ + 1, 6 );
   
    size_t foundE = wiersz_konwert.find( szukanyZnakE );
    if( foundE != string::npos )
         wiersz_konwert.insert( foundE - 1, wartoscZmiennejZ );
   
    return wiersz_konwert;
}


G0 F300 Z0.300
G0 X0.000 Y0.000 F10800
G0 F4800 G0 F48E0.0000
G1 X149.505 Y113.865 G1 X14E9.3758 F600
G1 X149.505 Y86.250 G1 X14E10.7535
G1 X152.946 Y86.250 G1 X15E10.9251
P-162636
pekfos
» 2017-06-17 21:00:02
A gdzie test, czy znaleziono 'Z'?
P-162638
« 1 » 2 3
  Strona 1 z 3 Następna strona