Wklejanie co drugiego znaku tablicy do innej tablicy.

0

Cześć,

rozwiązuję zadanie z książki Grębosza i prawie udało mi się je rozwiązać. Treść:

Mamy dwie tablice znakowe o identycznej długości. W jednej z nich znajduje się C-string. Napisz funkcję, która przekopiuje co drugą literę z jednej tablicy do drugiej (...).

To, co udało mi się wyskrobać:

#include <cstdlib>
#include <iostream>
#include <cstdio>

using namespace std;


void klej(char cel[], char zrodlo[]);
int main(int argc, char** argv) {

char tablica1[] = {"Tekst bez większego znaczenia"};
char tablica2[sizeof(tablica1)];

klej(tablica2, tablica1);

for (int j = 0;j<=sizeof(tablica2);j++)
    {
        cout << tablica2[j];
    }

cout << endl << sizeof(tablica2) << endl;

    return 0;
}
 
void klej(char cel[], char zrodlo[])
{
    int k = 0;
    for(int i = 0;i<sizeof(zrodlo);i++) 
    {
        if (i%2==0)
        {
            cel[k]=zrodlo[i];
            k++;
        }
    }
}

Rezultat:
Tktb00020`000
31

Dlaczego tylko pierwsze cztery litery są skopiowane prawidłowo, a kolejne znaki to null (zastąpiłem znak null zerami - nie potrafiłem przekopiwać..), dwójka i apostrof?

4
  1. sizeof nie do tego służy. Polecam strlen. Ty w funkcji przyjąłeś wskaźnik i obliczyłeś jego wielkość - na większości 32-bitowych architektur jest to 4 bajty.
  2. ponadto C++ ma dużo lepsze narzędzia do rozwiązania tego typu zadań
  3. nie ustawiasz znaku zerowego na końcu stringa
  4. popraw formatowanie
0
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

void klej(char cel[], char zrodlo[]);
int
main(int argc, char** argv)
{
  char tablica1[] = { "Tekst bez wiekszego znaczenia " };
  char tablica2[strlen(tablica1)];

  klej(tablica2, tablica1);

  for (int j = 0; j <= strlen(tablica2); j++) {
    cout << tablica2[j];
  }

  cout << endl << strlen(tablica2) << endl;

  return 0;
}

void
klej(char cel[], char zrodlo[])
{
  int k = 0;
  for (int i = 0; i < strlen(zrodlo); i++) {
    if (i % 2 == 0) {
      cel[k] = zrodlo[i];
      k++;
    }
  }
}

Rezultat:
Tktbzweseozazna
15

Działa! Dzięki za odpowiedź.
Dlaczego jeżeli w stringu znajduje się polski znak (w tym przypadku ę), rezulat jest wtedy zły, a string ma długość 16 (a nie 15)?
Nie zrozumiałem jednak, dlaczego należy ustawić znak zerowy na końcu stringa?

4

Bo tak działają C-stringi normalnie - są wyświetlane do napotkania znaku \0 (runtime/funkcja/kompilator często nie ma nawet jak sprawdzić wielkości tablicy)

co do polskich znaków - zaznajom się z pojęciami ASCII/unicode (google). W skrócie: ze względu na sposób zapisu tekstu, w jednym bajcie można zakodować tylko określoną liczbę znaków, a żeby pokazać inne trzeba kombinować.

Jeszcze jedno: wielkość tablicy musi być stałą kompilacji, więc sizeof w definicji tablica2 był akurat poprawny :D

1

char jest 1 bajtowy. Przewaznie (95%) jest to 8 bitow. Czyli mozesz zapisac do 255 wartosci.
http://www.asciitable.com/
tutaj masz wartosc kazdego znaku do 255.

Jezeli chcesz polskie znaki musisz uzyc wchar_t ktory ma 2 bajty i moze posiadac unicode

Najlepiej bedzie jak po prostu uzyjesz std::string z odpowiednim kodowaniem

0

A czy w tablicy ze stringiem znak null nie jest dodawany domyślnie?

3

Literał tekstowy zawiera znak końca stringa, tak. Ale zmienna tablica2 nie była niczym zainicjalizowana.

0

Wielkie, wielkie dzięki!

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