Macierz 10x10 charow

Macierz 10x10 charow
M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Wyskakują mi krzaczki zamiast tablicy charow 10x10. Czyli 100 znaków chara bym chciał wyświetlić. Poproszę o pomoc w wyświetleniu.

Kopiuj

#include <stdio.h>



int main() {
char a[9][9]={(0,0,0,0,0,0,0,0,0,0)};
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}

int i=0,j=0,k=0;

printf("Podaj element tablicy:");
for(i = 0; i < 10; i++){

for(j = 0; j < 10; j++)
{
scanf("%c", &a[i]);
scanf("%c", &a[j]);

}
}
printf("\nWynik:\n:");
for(i = 0; i < 10; i++){
for(j = 0; j < 10; j++){
printf("%c", a[i]);
printf("%c", a[j]);
}}
return 0;
}

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Można też drukować a[i][j] odrazy ale jak to wydrukować prawidlowo

elwis
  • Rejestracja: dni
  • Ostatnio: dni
1

Aż dziwne, że nie wysypuje się z naruszeniem ochrony pamięci, poza tym powinieneś dostać ostrzeżenie (chyba że masz wyłączone).

Kopiuj
scanf("%c", &a[i]);
scanf("%c", &a[j]);

a jest typu char**, więc a[i] jest typu char* i oznacza i-tą kolumnę macierzy (a właściwie wskaźnik do miejsca gdzie ona się znajduje). To co tu robisz to nadpisujesz adres tej kolumny i dlatego wskazuje na jakieś śmieci. Być może w tym wypadku nadpisywany jest tylko najmniej znaczący bajt adresu, więc dalej mieści się w legalnych adresach.

Ten fragment powinien wygladać:

Kopiuj
scanf("%c", &a[i][j]);

Odnosisz się do a[i][j]czyli kolumna i, wiersz j. Natomiast & pobiera adres tej komórki. Analogicznie powinieneś zrobić z printem.

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
1

https://godbolt.org/z/51s7xPcef

Kopiuj
<source>: In function 'main':
<source>:12:21: error: format '%c' expects argument of type 'char *', but argument 2 has type 'char (*)[9]' [-Werror=format=]
   12 |             scanf("%c", &a[i]);
      |                    ~^   ~~~~~
      |                     |   |
      |                     |   char (*)[9]
      |                     char *
<source>:13:21: error: format '%c' expects argument of type 'char *', but argument 2 has type 'char (*)[9]' [-Werror=format=]
   13 |             scanf("%c", &a[j]);
      |                    ~^   ~~~~~
      |                     |   |
      |                     |   char (*)[9]
      |                     char *
<source>:19:22: error: format '%c' expects argument of type 'int', but argument 2 has type 'char *' [-Werror=format=]
   19 |             printf("%c", a[i]);
      |                     ~^   ~~~~
      |                      |    |
      |                      int  char *
      |                     %s
<source>:20:22: error: format '%c' expects argument of type 'int', but argument 2 has type 'char *' [-Werror=format=]
   20 |             printf("%c", a[j]);
      |                     ~^   ~~~~
      |                      |    |
      |                      int  char *
      |                     %s
<source>:7:23: error: unused variable 'k' [-Werror=unused-variable]
    7 |     int i = 0, j = 0, k = 0;
      |                       ^
Kopiuj
=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x763079300071 at pc 0x7a307c0ac83c bp 0x7ffe0958f2e0 sp 0x7ffe0958eaa0
WRITE of size 1 at 0x763079300071 thread T0
    #0 0x7a307c0ac83b  (/opt/compiler-explorer/gcc-15.2.0/lib64/libasan.so.8+0xaa83b) (BuildId: 620b620e803590cdaf76f7a713f6c544a53408b6)
    #1 0x7a307c0eccb9 in __isoc99_vscanf (/opt/compiler-explorer/gcc-15.2.0/lib64/libasan.so.8+0xeacb9) (BuildId: 620b620e803590cdaf76f7a713f6c544a53408b6)
    #2 0x7a307c0ed304 in __isoc99_scanf (/opt/compiler-explorer/gcc-15.2.0/lib64/libasan.so.8+0xeb304) (BuildId: 620b620e803590cdaf76f7a713f6c544a53408b6)
    #3 0x00000040123f in main /app/example.c:13
    #4 0x7a307b629d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #5 0x7a307b629e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #6 0x000000401494 in _start (/app/output.s+0x401494) (BuildId: 5c6e8db49081598a8869190e8a008036bb774160)

Address 0x763079300071 is located in stack of thread T0 at offset 113 in frame
    #0 0x0000004010ef in main /app/example.c:4

  This frame has 1 object(s):
    [32, 113) 'a' (line 5) <== Memory access at offset 113 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /app/example.c:13 in main
M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Już poradziłem sobie dziekuje

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Tak pisałem o tym pod postem że można Od razu dac

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
2

Tak jak już ci pisałem dodaj do swojego kompilatora więcej flag ostrzeżeń.
Dla gcc: -Wall -Wextra -pedantic -fanalyzer - uchroni cię to przed wieloma błedami.

Używanie "address/undefined sanitzer" dodaje kod wykrywający większość błędów pamięci (narzędzie do diagnostyki). To tez powinno ci pomóc wykrywać błędy zawczasu.
Dodaj -fsanitize=address,undefined.

https://godbolt.org/z/17f4EEK5x

BR
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 43
2

Ja chciałbym zwrócić uwagę na coś innego. Konkretnie na ten fragment:

Kopiuj
char a[9][9]={(0,0,0,0,0,0,0,0,0,0)};
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}
{(0,0,0,0,0,0,0,0,0,0);}

To nie robi tego czego ktoś mógłby oczekiwać.

{(0,0,0,0,0,0,0,0,0,0);} to są osobne bloki kodu a przecinek jest operatorem. To nie jest lista dziesięciu zer tylko jedno zero. Ten kod robi coś takiego:

  • wykonaj wszystkie wyrażenia po kolei
  • wartością całego wyrażenia jest ostatnie
  • nic nie rób z wynikiem

Czyli pierwsza linia to efektywnie char a[9][9]={0}; a pozostałe nie robią nic sensownego. Działa tylko przypadkiem bo dostajesz poprawnie wyzerowaną tablicę 9x9. Ale nie dlatego że podane zostało 10 (czy tam 100) zer tylko dlatego że podałeś jedno zero. Jeśli lista inicjalizacyjna nie zawiera wystarczającej liczby elementów, pozostałe elementy są inicjalizowane zerem. Czyli:

  • a[0][0] = 0
  • cała reszta automatycznie = 0

Poprawnie to powinno wyglądać tak:

Kopiuj
char a[2][2]={{0,1},{2,3},{4,5}};

No chyba że chodzi o zera to wtedy char a[9][9]={0}; wystarczy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.