473,406 Members | 2,369 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Vigenere Cipher

Hi!

Here you can get some notes about Vigenere Cipher:
http://raphael.math.uic.edu/~jeremy/crypt/vignere.html

Here's whole code of my program, function stats() is in polish, so you
can omit it. The problem is that the encrypting function is not working
correctly, so I didn't write decryptying function. Plz, can you help me
with both issues?

#include <stdio.h>

#define IN 1 /* wewnątrz słowa */
#define OUT 0 /* poza słowem */

/* Vigenere Cipher */
/* deklaracje fuknkcji uzytych w programie */
int wypelnij_male(char tab[][]);
int wypelnij_duze(char tab[][]);
char haslo(int ii, char pass[]);
void koduj_numer(char c);
void szyfruj();
void deszyfruj();
void stats();

main() {

/* menu programu */
int menu;
for(;;){
printf("\n");
printf("1. Szyfrowanie tekstu.\n");
printf("2. Deszyfrowanie tekstu.\n");
printf("3. Statystyka.\n");
printf("4. Zakonczenie programu.\n");
scanf("%d", &menu);
switch(menu) {

case 1: szyfruj(); break;
case 2: deszyfruj();
case 3: stats();
case 4: return;
default: return;
}
}
}
void szyfruj(){

int ii, c, i, s;
char pass[]={0};

char MALE[26][26]={0};
char DUZE[26][26]={0};

wypelnij_male(MALE);
wypelnij_duze(DUZE);

printf("Podaj haslo: ");
scanf("%s\0", &pass);
getchar();
printf("Podaj tekst do zaszyfrowania:\n");

for (ii = 0; (c = getchar()) != '\n'; ++ii) {
if (c >= 'a' && c <= 'z') {
putchar(MALE[c - 'a'][haslo(ii, pass) - 'a']);
}
else if (c >= 'A' && c <= 'Z') {
putchar(DUZE[c - 'A'][haslo(ii, pass) - 'A']);
}
else koduj_numer(c);

}

putchar('\n');
getchar();
system("cls");
/*
!!!!!!!!!!!!!!!!!!!!!
tu czyszczenie ekranu
!!!!!!!!!!!!!!!!!!!!!
*/
}
/* Funkcja wypelniajaca tablice dwuwymiarowa malymi literami alfabetu */

int wypelnij_male(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]=('a' + ((yy+xx) % 26));

}

/* Funckja wypelniajaca tablice dwuwymiarowa wiekimi literami alfabetu */

int wypelnij_duze(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]='A' + ((yy+xx) % 26);
}

/* Fukncja zwracajaca aktualna litere w hasle */

char haslo(int ii, char pass[]) {

int k;
k = ii % (sizeof(pass));

return pass[k];
}

void koduj_numer(char c){putchar(c);}
void deszyfruj(){}

void stats() {

int c, state, num_lines, num_words, num_chars, num_let, num_digit,
num_spec;

state = OUT;
num_lines = num_words = num_chars = num_let = num_digit = num_spec = 0;

while ((c = getchar()) != '\t') {
++num_chars;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
c = 1;
num_let = num_let + c;
}
if (c >= '0' && c <= '9') {
c = 1;
num_digit = num_digit + c;
}
if (c == '\n')
++num_lines;
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++num_words;
}
}

num_spec = num_chars - (num_let + num_digit);

printf("Statystyki tekstu:\n\n");
printf("\tIlosc wszystkich znakow: %d\n", num_chars);
printf("\tIlosc wszyskich slow: %d\n", num_words);
printf("\tIlosc liter: %d", num_let);
printf("\tIlosc cyfr: %d", num_digit);
printf("\tIlosc znakow specjalnych: %d", num_spec);

getchar();
getchar();
system("cls");
}

--
Best regards, Piotr Turkowski
http://www.elfiaknieja.tk/
Nov 14 '05 #1
7 6809
"Piotr Turkowski" <pi***@ust.tke.pl> wrote in message
news:c0**********@nemesis.news.tpi.pl...
Hi!

Here you can get some notes about Vigenere Cipher:
http://raphael.math.uic.edu/~jeremy/crypt/vignere.html

Here's whole code of my program, function stats() is in polish, so you
can omit it. The problem is that the encrypting function is not working
correctly, so I didn't write decryptying function. Plz, can you help me
with both issues?
Which "both" issues? The fact that stats() is in Polish and that you haven't
written the decrypting function? No, I cannot help with the two ;-)

Now seriously. Your program seems a bit overcomplicated for such a simple
cipher. It also heavily relies on ASCII coding. In general, it is not
guaranteed that 'a'..'z' or 'A'..'Z' are contiguous. If you don't believe
me, Google for "EBCDIC".

I have added some comments interspersed with your code, but do not expect
that they are complete.
#include <stdio.h>

#define IN 1 /* wewnątrz słowa */
#define OUT 0 /* poza słowem */

/* Vigenere Cipher */

/* deklaracje fuknkcji uzytych w programie */
int wypelnij_male(char tab[][]);
int wypelnij_duze(char tab[][]);
This declaration as good as nothing. I am surprised it even compiles. Only
the first index range may be left unspecified, e.g.

int wypelnij_male(char tab[][42]);

Besides, a few lines below you actually define the functions as

int wypelnij_male(char tab[26][26]) {...}

Doesn't your compiler complain about definition not matching the prototype?
If not, turn up your warning level.
char haslo(int ii, char pass[]);
void koduj_numer(char c);
void szyfruj();
void deszyfruj();
void stats();

main() {
This form is deprecated. Better spell it out: int main (void).
/* menu programu */
int menu;
for(;;){
printf("\n");
printf("1. Szyfrowanie tekstu.\n");
printf("2. Deszyfrowanie tekstu.\n");
printf("3. Statystyka.\n");
printf("4. Zakonczenie programu.\n");
scanf("%d", &menu);
scanf() is not an ideal function, although it seems that every beginner's
class starts with scanf(). I don't know why.

Do you know what happens if you enter "Ham and eggs 4 me, please", followed
by Enter? Your scanf() will try to read a decimal integer as dictated by %d
and stop on the space after 4. Any standard input function will read the
space (and whatever follows, up to the end of the line). If that's what you
want, OK.
switch(menu) {

case 1: szyfruj(); break;
case 2: deszyfruj();
case 3: stats();
case 4: return;
default: return;
return what? Your main in (correctly, though implicitly) int, so give it
one. I bet you turned your warning level *down*, didn't you?
}
}
}
void szyfruj(){
This function takes no arguments and returns nothing. So what does it do?
int ii, c, i, s;
char pass[]={0};
What do you think this declaration does? I'll tell you: it declares an array
pass of type char. The size of the array is unspeified, so the compiler has
to look right at the initializer list. Which contains how many
initializaerz? Correct, only one! So your declaration is equivalent to char
pass[1] = {0};
char MALE[26][26]={0};
char DUZE[26][26]={0};

wypelnij_male(MALE);
wypelnij_duze(DUZE);
See my comments on these two functions above.
printf("Podaj haslo: ");
scanf("%s\0", &pass);
getchar();
Why do you need the \0 in scanf? And why do you need getchar? Isn't it
because of using scanf to read the menu item in main?
printf("Podaj tekst do zaszyfrowania:\n");

for (ii = 0; (c = getchar()) != '\n'; ++ii) {
if (c >= 'a' && c <= 'z') {
putchar(MALE[c - 'a'][haslo(ii, pass) - 'a']);
}
else if (c >= 'A' && c <= 'Z') {
putchar(DUZE[c - 'A'][haslo(ii, pass) - 'A']);
}
else koduj_numer(c);

Have you heard about isalpha and tolower? They are defined in ctype.h and
would make your life much easier. And your code much more portable (your
only works on ASCII systems). Compare your code with:

if (isalpha(c))
putchar(MALE[tolower(c) - 'a'][haslo(ii, pass) - 'a']);
else
koduj_numer(c);

Admittedly, it *still* relies on ASCII coding (the -'a' bit). Resolving that
would require a bit more work, but not *that* much.
}

putchar('\n');
getchar();
system("cls");
Is this really necessary?
/*
!!!!!!!!!!!!!!!!!!!!!
tu czyszczenie ekranu
!!!!!!!!!!!!!!!!!!!!!
*/
}
/* Funkcja wypelniajaca tablice dwuwymiarowa malymi literami alfabetu */

int wypelnij_male(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]=('a' + ((yy+xx) % 26));

}
As mentined aforehand, the definition does not match the prototype. Plus, it
relies on ASCII coding. Also, I stylistically prefer for (yy = 0; yy < 26;
yy++).
/* Funckja wypelniajaca tablice dwuwymiarowa wiekimi literami alfabetu */

int wypelnij_duze(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]='A' + ((yy+xx) % 26);
}
What is a difference between this function and the one above? The only one
that I can see is using 'A' instead of 'a'. Why don't you make it one
function and pass the constant as a parameter?
/* Fukncja zwracajaca aktualna litere w hasle */

char haslo(int ii, char pass[]) {

int k;
k = ii % (sizeof(pass));
Ha! What's sizeof(pass) here? Hint: it is not 1, as one would expect given
the declaration of pass in your main().
Answer: in function calls, arrays decay to pointers, so your char pass[] is
equivalent to char * pass. Therefore, sizeof(pass) is a size of a pointer on
your system. Given your DOS system() call, I take an educated guess that
sizeof(pass) is either 2 or 4, depending on how you compile your program.
return pass[k];
Undefined behaviour. Your pass is passed (no pun intended) from main, where
it is declared as having one element. For any k other than 0, the program
may do pretty much whatever it pleases.
}

void koduj_numer(char c){putchar(c);}
void deszyfruj(){}

void stats() {
I am ignoring this function, as you suggested at the beginning ;-)
int c, state, num_lines, num_words, num_chars, num_let, num_digit,
num_spec;

state = OUT;
num_lines = num_words = num_chars = num_let = num_digit = num_spec = 0;
while ((c = getchar()) != '\t') {
++num_chars;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
c = 1;
num_let = num_let + c;
}
if (c >= '0' && c <= '9') {
c = 1;
num_digit = num_digit + c;
}
if (c == '\n')
++num_lines;
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++num_words;
}
}

num_spec = num_chars - (num_let + num_digit);

printf("Statystyki tekstu:\n\n");
printf("\tIlosc wszystkich znakow: %d\n", num_chars);
printf("\tIlosc wszyskich slow: %d\n", num_words);
printf("\tIlosc liter: %d", num_let);
printf("\tIlosc cyfr: %d", num_digit);
printf("\tIlosc znakow specjalnych: %d", num_spec);

getchar();
getchar();
system("cls");
}

--
Best regards, Piotr Turkowski
http://www.elfiaknieja.tk/

Nov 14 '05 #2
Użytkownik Peter Pichler napisał:
Which "both" issues? The fact that stats() is in Polish and that you haven't
written the decrypting function? No, I cannot help with the two ;-)
badly decrypting, and no encrypting :)
Now seriously. Your program seems a bit overcomplicated for such a simple
cipher. It also heavily relies on ASCII coding. In general, it is not
guaranteed that 'a'..'z' or 'A'..'Z' are contiguous. If you don't believe
me, Google for "EBCDIC".
I'll check.
/* deklaracje fuknkcji uzytych w programie */
int wypelnij_male(char tab[][]);
int wypelnij_duze(char tab[][]);

This declaration as good as nothing. I am surprised it even compiles. Only
the first index range may be left unspecified, e.g.

int wypelnij_male(char tab[][42]);

Besides, a few lines below you actually define the functions as

int wypelnij_male(char tab[26][26]) {...}

Doesn't your compiler complain about definition not matching the prototype?
If not, turn up your warning level.


Declaration will be corrected.
I use Dev-C++ 4980 and it didn't warn me about problem in here.
This form is deprecated. Better spell it out: int main (void).
OK.
scanf() is not an ideal function, although it seems that every beginner's
class starts with scanf(). I don't know why.

Do you know what happens if you enter "Ham and eggs 4 me, please", followed
by Enter? Your scanf() will try to read a decimal integer as dictated by %d
and stop on the space after 4. Any standard input function will read the
space (and whatever follows, up to the end of the line). If that's what you
want, OK.
Yeah, I know, I tried :) This is version 0.0001 alpha beta pre relaease
1 :))
switch(menu) {

case 1: szyfruj(); break;
case 2: deszyfruj();
case 3: stats();
case 4: return;
default: return;

return what? Your main in (correctly, though implicitly) int, so give it
one. I bet you turned your warning level *down*, didn't you?


No, I didn't :). And return nothing :) just shutdown the program. This function takes no arguments and returns nothing. So what does it do?
It's decrypting, it don't have to return anything, it just have to write
decrypted text, and that's all.
int ii, c, i, s;
char pass[]={0};


What do you think this declaration does? I'll tell you: it declares an array
pass of type char. The size of the array is unspeified, so the compiler has
to look right at the initializer list. Which contains how many
initializaerz? Correct, only one! So your declaration is equivalent to char
pass[1] = {0};


Hmm, i don't know how long the password will be. So how should it look like?
printf("Podaj haslo: ");
scanf("%s\0", &pass);
getchar();


Why do you need the \0 in scanf? And why do you need getchar? Isn't it
because of using scanf to read the menu item in main?


I don't think so. I was thinking, that without \n or \0 it would read
one char too much, and without getchar(); program run too fast.
printf("Podaj tekst do zaszyfrowania:\n");

for (ii = 0; (c = getchar()) != '\n'; ++ii) {
if (c >= 'a' && c <= 'z') {
putchar(MALE[c - 'a'][haslo(ii, pass) - 'a']);
}
else if (c >= 'A' && c <= 'Z') {
putchar(DUZE[c - 'A'][haslo(ii, pass) - 'A']);
}
else koduj_numer(c); Have you heard about isalpha and tolower? They are defined in ctype.h and
would make your life much easier. And your code much more portable (your
only works on ASCII systems). Compare your code with:

if (isalpha(c))
putchar(MALE[tolower(c) - 'a'][haslo(ii, pass) - 'a']);
else
koduj_numer(c);

Hmm, actualy, after encrypting I want to have same text as it was before
decrypting, so I need two alphabets. I'll try you function, but i think
that i would return all text BIG ot small.
putchar('\n');
getchar();
system("cls");

Is this really necessary?


Should I use: printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\"); instead of
system("cls"); ?? Version for linux will have system("clear"); ;-)
As mentined aforehand, the definition does not match the prototype. Plus, it
relies on ASCII coding. Also, I stylistically prefer for (yy = 0; yy < 26;
yy++).


I giva up. What would be your solution?
/* Funckja wypelniajaca tablice dwuwymiarowa wiekimi literami alfabetu */

int wypelnij_duze(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]='A' + ((yy+xx) % 26);
}

What is a difference between this function and the one above? The only one
that I can see is using 'A' instead of 'a'. Why don't you make it one
function and pass the constant as a parameter?


Beacause I'm not that skilled.
/* Fukncja zwracajaca aktualna litere w hasle */

char haslo(int ii, char pass[]) {

int k;
k = ii % (sizeof(pass));

Ha! What's sizeof(pass) here? Hint: it is not 1, as one would expect given
the declaration of pass in your main().
Answer: in function calls, arrays decay to pointers, so your char pass[] is
equivalent to char * pass. Therefore, sizeof(pass) is a size of a pointer on
your system. Given your DOS system() call, I take an educated guess that
sizeof(pass) is either 2 or 4, depending on how you compile your program.


And this is the problem called: 'incorrect decrypting' (in 90%).

--
Pozdrawiam, Piotr Turkowski
http://www.elfiaknieja.tk/
Nov 14 '05 #3
"Piotr Turkowski" <pi***@ust.tke.pl> wrote in message
news:c0**********@nemesis.news.tpi.pl...
Użytkownik Peter Pichler napisał:

Doesn't your compiler complain about definition not matching the prototype?
If not, turn up your warning level.
Declaration will be corrected.
I use Dev-C++ 4980 and it didn't warn me about problem in here.


The default warning level must be set low in your compiler. This is
unfortunately quite a common practise.
switch(menu) {

case 1: szyfruj(); break;
case 2: deszyfruj();
case 3: stats();
case 4: return;
default: return;


return what? Your main in (correctly, though implicitly) int, so give it
one. I bet you turned your warning level *down*, didn't you?


No, I didn't :). And return nothing :) just shutdown the program.


mani() is a function like any other. If it is declared int (and it is, in
your case, although implicitly), it must return an int. Use 'return 0;' and
you'll be fine.
char pass[]={0};


What do you think this declaration does? I'll tell you: it declares an array
pass of type char. The size of the array is unspeified, so the compiler has to look right at the initializer list. Which contains how many
initializaerz? Correct, only one! So your declaration is equivalent to char pass[1] = {0};


Hmm, i don't know how long the password will be. So how should it look

like?

So leave the decision for later. Declare a pointer and allocate memory
dynamically once you know how much you need. If that is too advanced for you
yet, think of a number that is "big enough" and declare pass accordingly.
printf("Podaj haslo: ");
scanf("%s\0", &pass);
I forgot to mention two things here:
1. Standard output is usually line-buffered. It means that nothing is
guaranteed to be printed before the next \n or before you force flush the
buffer by fflush(stdout).
2. Since your pass is only 1 character long and that is taken up by the
terminating zero, the scanf() above is most likely going to do something
nasty.
getchar();


Why do you need the \0 in scanf? And why do you need getchar? Isn't it
because of using scanf to read the menu item in main?


I don't think so. I was thinking, that without \n or \0 it would read
one char too much, and without getchar(); program run too fast.


It *does* read too much already, see my comments on the size of pass ;-)
As for the program "going too fast", I assume you mean it prints the
following text without waiting for your password. If that's the case, try
experimenting with your scanf()s. You have two, one in main() and one above,
both working with the same input buffer. The second one continues where the
first one finished, which may not be where you *think* it finished.
printf("Podaj tekst do zaszyfrowania:\n");

for (ii = 0; (c = getchar()) != '\n'; ++ii) {
if (c >= 'a' && c <= 'z') {
putchar(MALE[c - 'a'][haslo(ii, pass) - 'a']);
}
else if (c >= 'A' && c <= 'Z') {
putchar(DUZE[c - 'A'][haslo(ii, pass) - 'A']);
}
else koduj_numer(c);

Have you heard about isalpha and tolower? They are defined in ctype.h and
would make your life much easier. And your code much more portable (your
only works on ASCII systems). Compare your code with:

if (isalpha(c))
putchar(MALE[tolower(c) - 'a'][haslo(ii, pass) - 'a']);
else
koduj_numer(c);


Hmm, actualy, after encrypting I want to have same text as it was before
decrypting, so I need two alphabets. I'll try you function, but i think
that i would return all text BIG ot small.


You are right, I made a mistake. (It is not unusual, unfortunately.) I
didn't notice the difference between MALE a DUZE in your code.
Should I use: printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\"); instead of
system("cls"); ?? Version for linux will have system("clear"); ;-)
Do you need to clear the screen at all? Many users (including me) find it
annoying.
As mentined aforehand, the definition does not match the prototype. Plus, it relies on ASCII coding. Also, I stylistically prefer for (yy = 0; yy < 26; yy++).


I giva up. What would be your solution?


See below.
/* Funckja wypelniajaca tablice dwuwymiarowa wiekimi literami alfabetu */
int wypelnij_duze(char tab[26][26]) {
int xx, yy;

for (yy = 0; yy <= 25; yy++)
for (xx = 0; xx <= 25; xx++)
tab[yy][xx]='A' + ((yy+xx) % 26);
}


What is a difference between this function and the one above? The only one
that I can see is using 'A' instead of 'a'. Why don't you make it one
function and pass the constant as a parameter?


Beacause I'm not that skilled.


static const char male[] = "abcdefghijklmnopqrstuvwxyz";
static const char duze[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

static int wypelnij (char tab[26][26], const char alphabet[])
{
int xx, yy;

for (yy = 0; yy < 26; yy++)
for (xx = 0; xx < 26; xx++)
tab[yy][xx] = alphabet[(yy+xx) % 26];
}

int wypelnij_duze (char tab[26][26]) { return wypelnij(tab, duze); }
int wyplenij_male (char tab[26][26]) { return wypelnij(tab, male); }

No dependency on the character encoding, only one function to update should
you need to... The '26' could be replaced with a symbolic constant, to make
it more flexible.
/* Fukncja zwracajaca aktualna litere w hasle */

char haslo(int ii, char pass[]) {

int k;
k = ii % (sizeof(pass));


Ha! What's sizeof(pass) here? Hint: it is not 1, as one would expect given the declaration of pass in your main().
Answer: in function calls, arrays decay to pointers, so your char pass[] is equivalent to char * pass. Therefore, sizeof(pass) is a size of a pointer on your system. Given your DOS system() call, I take an educated guess that
sizeof(pass) is either 2 or 4, depending on how you compile your

program.
And this is the problem called: 'incorrect decrypting' (in 90%).


Solution: pass the size of the array as another parameter and use that
parameter instead of sizeof(pass) inside your function.

Peter
Nov 14 '05 #4
In article <c0**********@nemesis.news.tpi.pl>, pi***@ust.tke.pl says...
Doesn't your compiler complain about definition not matching the prototype?
If not, turn up your warning level.


Declaration will be corrected.
I use Dev-C++ 4980 and it didn't warn me about problem in here.


Dev-C++ is just a front end to gcc. You can change the invocation to
gcc in the project options, for such things as -Wall -O2 -ansi, etc.
It'll make the detection of a whole host of common errors much more
automagic. :-)

--
Randy Howard
2reply remove FOOBAR

Nov 14 '05 #5
On Sat, 7 Feb 2004 19:37:16 -0000, "Peter Pichler" <pi*****@pobox.sk>
wrote:
"Piotr Turkowski" <pi***@ust.tke.pl> wrote in message
news:c0**********@nemesis.news.tpi.pl... <snip>
/* deklaracje fuknkcji uzytych w programie */
int wypelnij_male(char tab[][]);
int wypelnij_duze(char tab[][]);


This declaration as good as nothing. I am surprised it even compiles. Only
the first index range may be left unspecified, e.g.

int wypelnij_male(char tab[][42]);

In C99 yes; this is (now) a constraint on the array declarator, that
the element type must be complete and hence not (sub)array with
unknown bound. In C89, questionable; that constraint did not exist,
and the only applicable requirement was on actual array types or maybe
objects in 6.1.2.5, and the actual object here is a (rewritten)
pointer not an array -- char (*)[], which is a legal type *if* the
rewriting happens before the element type is checked, which was not
specified -- and the requirement was not a constraint anyway.
Besides, a few lines below you actually define the functions as

int wypelnij_male(char tab[26][26]) {...}

Doesn't your compiler complain about definition not matching the prototype?
If not, turn up your warning level.

And rewritten char (*)[] is compatible with char (*)[26] according to
the type rules, which rely only on information available at (separate)
compile time, hence no required diagnostic. This usage is rather
dangerous -- for precisely the reasons you imply -- and could
reasonably be warned about, but that isn't required.

<many other good points snipped>

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #6
"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:nb********************************@4ax.com...
On Sat, 7 Feb 2004 19:37:16 -0000, "Peter Pichler" <pi*****@pobox.sk>
wrote:
"Piotr Turkowski" <pi***@ust.tke.pl> wrote in message
news:c0**********@nemesis.news.tpi.pl...

<snip>
/* deklaracje fuknkcji uzytych w programie */
int wypelnij_male(char tab[][]);
int wypelnij_duze(char tab[][]);


This declaration as good as nothing. I am surprised it even compiles. Only the first index range may be left unspecified, e.g.

int wypelnij_male(char tab[][42]);

In C99 yes; this is (now) a constraint on the array declarator, that
the element type must be complete and hence not (sub)array with
unknown bound. In C89, questionable; that constraint did not exist,
and the only applicable requirement was on actual array types or maybe
objects in 6.1.2.5, and the actual object here is a (rewritten)
pointer not an array -- char (*)[], which is a legal type *if* the
rewriting happens before the element type is checked, which was not
specified -- and the requirement was not a constraint anyway.


But these are not the same types! tab[12][34] has a different semantics when
tab is char[][42] than when it is char (*)[]. What is tab[12][34] in the
latter case anyway? Even if no constraints were broken, I would expect my
compiler to complain (as it does). A QoI issue...?

Peter
Nov 14 '05 #7
On Sun, 15 Feb 2004 15:46:27 -0000, "Peter Pichler" <pi*****@pobox.sk>
wrote:
"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:nb********************************@4ax.com...
On Sat, 7 Feb 2004 19:37:16 -0000, "Peter Pichler" <pi*****@pobox.sk>
wrote: (re function declaration using char x[][] vs char x[][known]) In C99 yes; this is (now) a constraint on the array declarator, that
the element type must be complete and hence not (sub)array with
unknown bound. In C89, questionable; that constraint did not exist,
and the only applicable requirement was on actual array types or maybe
objects in 6.1.2.5, and the actual object here is a (rewritten)
pointer not an array -- char (*)[], which is a legal type *if* the
rewriting happens before the element type is checked, which was not
specified -- and the requirement was not a constraint anyway.


But these are not the same types! tab[12][34] has a different semantics when
tab is char[][42] than when it is char (*)[]. What is tab[12][34] in the
latter case anyway? Even if no constraints were broken, I would expect my
compiler to complain (as it does). A QoI issue...?

Right. Precisely, if the actual object is char[any][34] and the
prototype is char[][] rewritten to char(*)[], what is passed is really
the decayed char(*)[34]. Within the body, the only fully correct
access is if you cast/convert back to char(*)[34] and use that; or go
down to the first row and use *x as char[] decayed to char* for 0..33.
If you wrongly convert to and use e.g. char(*)[42] it's undefined --
although in practice you will always get the corresponding element for
row-major layout, if it exists; there's no other reasonable way to
implement C "multidim" arrays. That's what I meant when I went on to
describe the usage as "rather dangerous". And thus yes a warning is
good QoI but not required. All in C89, of course.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Michael Sparks | last post by:
Hi, I suspect this is a bug with AMK's Crypto package from http://www.amk.ca/python/code/crypto , but want to check to see if I'm being dumb before posting a bug report. I'm looking at...
4
by: Carl Harris | last post by:
I am trying to write some code to: 1.Prompt a user for filenames 2.Open the files 3.Convert my plain text into a cipher text array/string bear in mind I am a novice! I have wriiten some code...
9
by: Piotr Turkowski | last post by:
Hi, The code is here: http://free.ud.pl/~piotr/data/vigenere.zip Its my program for decrypting and encrypting text. Shot polish course: szyfrowanie (szyfruj) - encrypting (text i want to code...
1
by: al.raiyes | last post by:
hi all i hope that anybody can help me to find a source program in C++ for Vigenere Table and i will be thankfull for you yours Al.Raiyes
2
by: Julio C. Hernandez Castro | last post by:
Dear all, We have just developped a new block cipher called Raiden, following a Feistel Network structure by means of genetic programming. Our intention now consists on getting as much feedback...
1
by: beetle17 | last post by:
Plaintext: a  n i c e  d a y Key: -3 Ciphertext: X  k f Z b  a X v Cipher will accept commands from the user and perform the operations required by the commands. There are three different...
4
by: wagn31 | last post by:
i need to use a cipher but I have to used the assigned code in the ciphering i know how to do it, but i am not sure how to add my own dictionary. Here is what i have so far:
2
by: yeruvavasavi | last post by:
Algorithm 1: Write python programs to translate the following algorithm so that the computer can execute it. Algorithm for ceaser cipher. Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ<br> Cipher: ...
3
by: hcarlens | last post by:
Hi all, I am having a problem with a vigenere decryption method I am writing. I have tried to solve this but really can't figure out why this is happening. I get a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.