Zapisywanie do pliku znaków z rozsz. ASCII

0

Witam.
Mam pewien problem. Muszę zapisywać znaki - nawet te z przedziału 128-255. Problem jest podobny przy odczytywaniu takich znaków z pliku, ale łatwo go można zniwelować w odróżnieniu do zapisu. Otóż przy odczycie takiego znaku z pliku do, na przykład, zmiennej char to przy sprawdzeniu wartości tego znaku dostaniemy wartość ujemną. Aby dobrze operować na wszystkich znakach wystarczyło zwiększyć wartości ujemne o 256. Problem jest podobny przy zapisie, ale niestety nawet po podaniu prawidłowych wartości znaków rozszerzonego ASCII ten uparcie zapisuje coś innego.

Przykładowy kod w DEVie sprawdzający ten 'bug':

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    int a;
    char b;
    cin >> a;
    b=(char)a;
    
    cout << b << ' ' << (int)b << ' ' << (char)a << ' ' << a << endl;
    
    FILE *ww;
    ww=fopen("abba.txt","w");
    fputc('a',ww);
    fputc('\n',ww);
    fputc(a,ww);
    fputc('\n',ww);
    fputc((char)a,ww);

    fputc('\n',ww);
    fputc('\n',ww);

    fputc('b',ww);
    fputc('\n',ww);
    fputc((int)b,ww);
    fputc('\n',ww);
    fputc(b,ww);

    fputc('\n',ww);
    fputc('\n',ww);

    if ((int)b<0) fputc(((int)b)+256,ww);
    
    fputc('\n',ww);
    fputc('\n',ww);

    fputc(161,ww);
    
    fclose(ww);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

Dla liczby 161 na ekran wyrzuci nam:

161
í -95 í 161
Press any key to continue . . .

a w pliku wyląduje:

a
ˇ
ˇ

b
ˇ
ˇ

ˇ

ˇ

Jak widać zamiast í zapisuje ˇ.
Informuję, że też przy zapisie strumieniowym, czy to stringów, czy charów efekt jest ten sam.

0

;-P ales pomotał jescze raz co chcesz zapisac i co odczytac :-P

0

Mam pewien problem. Muszę zapisywać znaki - nawet te z przedziału 128-255. Problem jest podobny przy odczytywaniu takich znaków z pliku, ale łatwo go można zniwelować w odróżnieniu do zapisu. Otóż przy odczycie takiego znaku z pliku do, na przykład, zmiennej char to przy sprawdzeniu wartości tego znaku dostaniemy wartość ujemną.

unsigned char użyj i po problemie masz wtedy 0-255.

0
Piotrekdp napisał(a)

Mam pewien problem. Muszę zapisywać znaki - nawet te z przedziału 128-255. Problem jest podobny przy odczytywaniu takich znaków z pliku, ale łatwo go można zniwelować w odróżnieniu do zapisu. Otóż przy odczycie takiego znaku z pliku do, na przykład, zmiennej char to przy sprawdzeniu wartości tego znaku dostaniemy wartość ujemną.

unsigned char użyj i po problemie masz wtedy 0-255.

Wystarczy, że dodam 256. Powiedz lepiej jak poprawnie zapisać taki znak do pliku by był jak należy, a nie coś innego.

(Jak zapisać znak ASCII o numerku 161 tak by w pliku wylądował znak í, a nie coś innego)

0

dodawanie wartosci jest niewydajne to po pierwsze
po drugie to jak widzisz znak to sprawa kodowania konsolki. jesli zapiszesz i odczytasz w konsolce bedzie oki

0

Jeżeli dobrze rozumiem to chodzi Ci o coś takiego:

kod.cpp

#include <cstdio>
#include <cstdlib>

int main(int argc, char ** argv){
    if(argc!=2){
        return 1;
    }

    if(atoi(argv[1])==0){
        return 1;
    }

    unsigned char c=(char)(atoi(argv[1]));
    unsigned char rd_c;

    FILE * f=fopen("wyjscie.txt", "w");
    fputc(c, f);
    fclose(f);

    f=fopen("wyjscie.txt", "r");
    rd_c=fgetc(f);
    fclose(f);

    printf("Zapisano ASCII %i, a nastepnie wczytano ASCII %i\n", c, rd_c);

    return 0;
}

Na linuksie:

$ g++ -o test kod.cpp
$ ./test 161
Zapisano ASCII 161, a nastepnie wczytano ASCII 161

Mam nadzieję, że w czymś to pomoże.

Pozdrawiam

0
venomxxl napisał(a)

Jeżeli dobrze rozumiem to chodzi Ci o coś takiego:

kod.cpp

#include <cstdio>
#include <cstdlib>

int main(int argc, char ** argv){
    if(argc!=2){
        return 1;
    }

    if(atoi(argv[1])==0){
        return 1;
    }

    unsigned char c=(char)(atoi(argv[1]));
    unsigned char rd_c;

    FILE * f=fopen("wyjscie.txt", "w");
    fputc(c, f);
    fclose(f);

    f=fopen("wyjscie.txt", "r");
    rd_c=fgetc(f);
    fclose(f);

    printf("Zapisano ASCII %i, a nastepnie wczytano ASCII %i\n", c, rd_c);

    return 0;
}

Na linuksie:

$ g++ -o test kod.cpp
$ ./test 161
Zapisano ASCII 161, a nastepnie wczytano ASCII 161

Mam nadzieję, że w czymś to pomoże.

Pozdrawiam

Nie do końca o to chodziło. Napisałem algorytm DESa do szyfrowania. Tekst szyfruje i deszyfruje bez problemu o ile wynik szyfrowania nie jest zapisywany do pliku. Chcę, a raczej muszę napisać jeszcze możliwość szyfrowania dowolnych plików.
Czyli powinna być możliwość zaszyfrowania np. pliku .exe, a potem odszyfrowania jego po czym powinien nadal być poprawny/działający. Ale tak się nie da, bo przy zapisie wstawia mi inne znaki niż powinno...
Tak samo Twój kod, co prawda po zapisie może odczytać prawidłową wartość, ale w pliku nadal się znajduje ˇ zamiast í. Odszyfrowany plik .exe który będzie miał w miejscu í znak ˇ nie ma prawa być poprawny. í jest prawidłowym znakiem ASCII o numerku 161.

Co ciekawe jak dam fputc('í',ww); to w pliku będzie to í, a jak dam fputc(161,ww); to uparcie wstawia ˇ.

0
xzyvvy napisał(a)

(...)
Nie do końca o to chodziło. Napisałem algorytm DESa do szyfrowania. Tekst szyfruje i deszyfruje bez problemu o ile wynik szyfrowania nie jest zapisywany do pliku. Chcę, a raczej muszę napisać jeszcze możliwość szyfrowania dowolnych plików.
Czyli powinna być możliwość zaszyfrowania np. pliku .exe, a potem odszyfrowania jego po czym powinien nadal być poprawny/działający. Ale tak się nie da, bo przy zapisie wstawia mi inne znaki niż powinno...
(...)

*.exe to pliki binarne, więc trzeba podejść do nich w inny sposób. Przed chwilą odpowiedziałem na inne pytanie w którym ktoś inny próbował "wczytać linijkę z pliku binarnego". Oczywiście tak się nie da. Mało wiem na temat czytania plików binarnych, ale znalazłem link który może Ci pomóc:
http://www.angelfire.com/country/aldev0/cpphowto/cpp_BinaryFileIO.html
Jeżeli nadal nie rozwiązuje to Twojego problemu to radzę przeszukać Google.

Pozdrawiam

0
venomxxl napisał(a)

*.exe to pliki binarne, więc trzeba podejść do nich w inny sposób. Przed chwilą odpowiedziałem na inne pytanie w którym ktoś inny próbował "wczytać linijkę z pliku binarnego". Oczywiście tak się nie da. Mało wiem na temat czytania plików binarnych, ale znalazłem link który może Ci pomóc:
http://www.angelfire.com/country/aldev0/cpphowto/cpp_BinaryFileIO.html
Jeżeli nadal nie rozwiązuje to Twojego problemu to radzę przeszukać Google.

Pozdrawiam

No dobra, ale to nie tłumaczy faktu, że źle zapisuje znaki z rozszerzonej tablicy ASCII.

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