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

[C++] Zmiana nazw plików (tworzenie pliku) polskie znaki.

Ostatnio zmodyfikowano 2015-01-11 23:21
Autor Wiadomość
Krump
Temat założony przez niniejszego użytkownika
» 2015-01-04 01:23:25
Zaraz zaraz, bo się pogubiłem. Nie jestem tak dobry w programowaniu. Bardziej łopatologicznie.

1. Nie mogę edytować pliku .txt (jest w UFT-8 i koniec, muszę na nim działać, no chyba, że w programie zrobię coś co mi przeformułuje ten plik na inne kodowanie)
2. Ta funkcja jakoś mi się nie widzi, szczerze to mało co ją na pierwszy rzut ogarniam.
3. Po za .exe nie mogę mieć dodatkowych plików, no chyba, że ten program sobie utworzy taki plik.

PS. Sorka i proszę o wyrozumiałość, ale ja działam, raczej na urządzeniach i ich sterowaniem  anie na plikach, dlatego to mi trochę na czarna magie wygląda. Całkiem inna strona programowania. Dlatego proszęe tak bardziej krok po kroczku, jak dziecku.
P-124053
SocrateZ
» 2015-01-04 01:41:17
UTF-8 z BOM czy bez?
Co do pliku. Chodzi mi o plik w którym przechowywane są nazwy plików (bo jest jeden, tak?). Kodowanie nie ma znaczenia w plikach w których nazwa będzie zmieniana.
Plik który zawiera nazwy plików po zmianie musi być zapisany w ANSI.
P-124055
Krump
Temat założony przez niniejszego użytkownika
» 2015-01-04 01:48:57
Czy z BOM to nie wiem, musisz mi powiedzieć jak to sprawdzić.

Tak, własnie mówię cały czas, plik z którego pobieramy dane do zmian nazw jest jeden, ale on jest w UTF-8 i nie mogę go edytować chyba, że mój program to zrobi i zakoduje go w ASCII. Nie mogę go edytować, bo będę dostawał ich bardzo wiele, dżinnie po kilkadziesiąt i teraz mi się nie widzi każdego przekodować ręcznie.
P-124058
SocrateZ
» 2015-01-04 02:04:22
Jedynym rozsądnym w tym momencie rozwiązaniem byłoby otwieranie pliku i zapisywanie zawartości do tablicy wchar_t, po czym konwertowanie tablicy wchar_t do char. W tym momencie nie jest potrzebna zmiana zawartości pliku, bo sama jest już zmieniona w pamięci. Wystarczy tylko zmienić nazwę wybranego pliku. Problem jest w konwersji z wchar_t do char. Pod jaki system to piszesz? W MS wiem że jest funkcja wcstombs
P-124060
Krump
Temat założony przez niniejszego użytkownika
» 2015-01-04 12:55:12
Obecnie pisze pod win7 w codeblocks 13.12, ale chciałbym aby program był uniwersalny na każdy system (pod linuksa i tak będę musiał pozmieniać pewnie).

Pliki u siebie ładuje do strigów, ponieważ łatwiej mi potem wykonywac na nich operacje cięcia w taki sposób:
C/C++
string filename;
while( !EE.eof() )
{
    lines++;
    getline( EE, filename );
    size_t columns = SearchSymbol( filename );
    if( EE.fail() ) break;
   
    if( columns == string::npos )
    {
        cout << "Sorry, there's problem in " << lines << "line. (Mabey Wrong Name Or No Symbol \" -> \")" << endl
        << "File name: " << filename << endl;
        EE.clear();
        continue;
    }
Następnie jak jestem już tuż przed zmianą nazwy rename(), to ze stirnga przechodzę na const char'a w taki sposób:
C/C++
string originalPath = filename.erase( columns, filename.size() - 1 );
const char * originalPath1 = originalPath.c_str();
P-124065
SocrateZ
» 2015-01-04 20:08:37
Działający przykład (przynajmniej na Windowsie).
C/C++
#include <stdio.h>
#include <string.h>

// -------------------------------------

int get_char_bytes( unsigned char val )
{
    if( val < 128 ) return 1;
    else if( val < 224 ) return 2;
    else if( val < 240 ) return 3;
   
    return 4;
}

// -------------------------------------

void _add_utf8_to_ansi_string( char * val, char * string, size_t * counter, size_t limit )
{
    size_t length = strlen( val ), x = 0;
   
    if( * counter + length > limit )
         return;
   
    while( x < length )
         string[( * counter ) ++ ] = val[ x++ ];
   
}

// -------------------------------------

void add_utf8_to_ansi_string( int val, char * string, size_t * counter, size_t limit )
{
    if( * counter + 1 > limit )
         return;
   
    if( val <= 0x7F )
         string[( * counter ) ++ ] =( char ) val;
    else switch( val )
    {
    case 0xC484: _add_utf8_to_ansi_string( "Ą", string, counter, limit ); break;
    case 0xC485: _add_utf8_to_ansi_string( "ą", string, counter, limit ); break;
    case 0xC486: _add_utf8_to_ansi_string( "Ć", string, counter, limit ); break;
    case 0xC487: _add_utf8_to_ansi_string( "ć", string, counter, limit ); break;
    case 0xC498: _add_utf8_to_ansi_string( "Ę", string, counter, limit ); break;
    case 0xC499: _add_utf8_to_ansi_string( "ę", string, counter, limit ); break;
    case 0xC581: _add_utf8_to_ansi_string( "Ł", string, counter, limit ); break;
    case 0xC582: _add_utf8_to_ansi_string( "ł", string, counter, limit ); break;
    case 0xC393: _add_utf8_to_ansi_string( "Ó", string, counter, limit ); break;
    case 0xC3B3: _add_utf8_to_ansi_string( "ó", string, counter, limit ); break;
    case 0xC59A: _add_utf8_to_ansi_string( "Ś", string, counter, limit ); break;
    case 0xC59B: _add_utf8_to_ansi_string( "ś", string, counter, limit ); break;
    case 0xC5BB: _add_utf8_to_ansi_string( "Ż", string, counter, limit ); break;
    case 0xC5BC: _add_utf8_to_ansi_string( "ż", string, counter, limit ); break;
    case 0xC5B9: _add_utf8_to_ansi_string( "Ź", string, counter, limit ); break;
    case 0xC5BA: _add_utf8_to_ansi_string( "ź", string, counter, limit ); break;
    case 0xC583: _add_utf8_to_ansi_string( "Ń", string, counter, limit ); break;
    case 0xC584: _add_utf8_to_ansi_string( "ń", string, counter, limit ); break;
    }
}

// -------------------------------------

int main( int argc, char ** argv )
{
    FILE * data = NULL;
    int sign = 0;
    size_t x = 0, y = 0;
    char nfname[ 256 ] = { 0 };
    int resnum = 0;
   
    data = fopen( "data.txt", "r" );
    if( !data ) return 1;
   
    while(( sign = fgetc( data ) ) != EOF && x < 255 )
    {
        resnum = 0;
        y = get_char_bytes(( unsigned char ) sign );
       
        while( --y > 0 )
        {
            resnum |= sign << 8 * y;
            printf( "%d ", sign );
            sign = fgetc( data );
        }
       
        printf( "%d ", sign );
        resnum |= sign;
       
        printf( "%d (0x%X)\n", resnum, resnum );
        add_utf8_to_ansi_string( resnum, nfname, & x, 256 );
    }
   
    printf( "%s\n", nfname );
   
    data = fopen( "test.txt", "w" );
    if( !data ) return 1;
   
    fclose( data );
    rename( "test.txt", nfname );
   
    getchar();
    return 0;
}

Sprawdź czy działa. Kod działa dla UTF-8. Ale jedno ale. Plik źródłowy który kompilujesz musi być (przynajmniej na VisualStudio) zapisany w kodowaniu cp1250 lub UTF-8 (cp65001) z sygnaturą (czyli z BOM) - kodowanie możesz zmienić w programie Notepad i skompilować gcc (program napisany jest w C - nie nawidzę C++ i staram się go omijać szerokim łukiem).

Nie wiem również jak program zachowa się pod linuksem. Musisz to sprawdzić.

PS: Oczywiście plik data.txt musisz mieć utworzony. Kodowanie UTF-8, zawartość np. taka:
Zażółć-żółtą-jaźń.txt
P-124132
Krump
Temat założony przez niniejszego użytkownika
» 2015-01-05 00:11:10
Kurcze i nie ma innej metody? Jakiegoś prze formatowania już w kodzie po zainicjowaniu. To mi bardzo psuje wszystko, gdyż bardzo dużo operacji i algorytm potężny mam napisany na stringach i wolał bym coś, co mi tuż przed renamem przerobi znaki na polskie, od razu po wczytaniu. Fajnie by było  w C++ a nie w C, bo to jednak już w takim programowaniu robi różnicę.
P-124165
SocrateZ
» 2015-01-05 00:23:22
Funkcja getline pobiera tablicę znaków char, więc prawdopodobnie możesz powyższy kod zmienić do swoich potrzeb.
Wystarczy iterować po znakach z tablicy pobranych funkcją getline. Zmieniasz tylko składniki i warunek dla while.

http://www.cplusplus.com​/reference/string/string/

Kod w case to identyfikator znaku UTF w kodzie szesnastkowym.
P-124167
1 « 2 » 3 4 5
Poprzednia strona Strona 2 z 5 Następna strona