for loop skips items

Q

Qu?bec

How comes the for loop just printf 3 characters?

1 e
7 e
10 e

The string mixed by C is : J?an Pi?rr?

=========
fmt string is "Jean Pierre"
---------------
const char *fmt;
.....
strcpy(ligne, fmt);
....
for(i=0;i<11;i++){
for(j=0;j<65;j++){
if(alphabet[j] == fmt){
ligne = alphabet[65-j];
printf("%d %c\n", i, fmt);
break;
}
}

}

===
char alphabet[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z', '_', '-'};
 
J

Joe Pfeiffer

Qu?bec said:
How comes the for loop just printf 3 characters?

1 e
7 e
10 e

I'm guessing there's something important in the code you edited out:

#include <stdio.h>

const char fmt[] = "Jean Pierre";

char alphabet[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z', '_', '-'};

int main()
{
int i, j;
for(i=0;i<11;i++){
for(j=0;j<65;j++){
if(alphabet[j] == fmt){
printf("%d %c\n", i, fmt);
break;
}
}

}
}

snowball:537$ ./bogus
0 J
1 e
2 a
3 n
4
5 P
6 i
7 e
8 r
9 r
10 e
snowball:538$
 
Q

Qu?bec

Qu?bec said:
How comes the for loop just printf 3 characters?

1 e
7 e
10 e

I'm guessing there's something important in the code you edited out:

#include <stdio.h>

const char fmt[] = "Jean Pierre";

char alphabet[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z', '_', '-'};

int main()
{
int i, j;
for(i=0;i<11;i++){
for(j=0;j<65;j++){
if(alphabet[j] == fmt){
printf("%d %c\n", i, fmt);
break;
}
}

}
}

snowball:537$ ./bogus
0 J
1 e
2 a
3 n
4
5 P
6 i
7 e
8 r
9 r
10 e
snowball:538$


Hi again sorry for the missing code, I thought it was too much. If you
never did JNI stay away, you may be scared :)

Anyway, now I am sure the for loops where good.

Java calls C witch returns the modified string with the jstring ret.

Here is the out put

The string 'Jean Pierre' received by C has 11 characters.
fmt- e -80- Ã
fmt- e -80- Ã
fmt- e -80- Ã
fmt- 85- Ã
The string mixed by C is : [?om8§
in java: [?om8§

Thanks

Jean


===========
#include "Serial.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#define JNI_FALSE 0
#define JNI_TRUE 1

char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " <from a
friend on this group ...
"abcdefghijklmnopqrstuvwxyz_-";
const int alphas = sizeof alphabet - 1;

JNIEXPORT jstring JNICALL Java_Serial_numero
(JNIEnv *env, jobject jobjc, jstring jstr){
jboolean iscopy;
jstring ret;
jsize len;
int i, j;
const char *fmt;
char alphabet[65];
char ligne[12];

fmt = (*env)->GetStringUTFChars(env, jstr, &iscopy);
len = (*env)->GetStringLength(env, jstr);

printf("The string '%s' received by C has %d characters.\n", fmt, len );

for(i=0;i<11;i++){
for(j=0;j<alphas;j++){
if(alphabet[j] == fmt){
printf("fmt- %c ", fmt);
ligne = alphabet[65-j];
printf("%d- %c\n",ligne);
break;
}
}
}

ligne[12] = '\0';
printf("The string mixed by C is : %s\n", ligne);

ret = (jstring)(*env)->NewStringUTF(env, ligne);
(*env)->ReleaseStringUTFChars(env, jstr, fmt);

return ret;
}

=================
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Serial */

#ifndef _Included_Serial
#define _Included_Serial
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Serial
* Method: numero
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_Serial_numero
(JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}

#endif
#endif
===========

public class Serial
{ static
{
System.loadLibrary("serial");
}

public static void main(String[] args)
{
Serial serie = new Serial();
String fromC = serie.numero("Jean Pierre");
System.out.println("in java: " + fromC);
}

public native String numero(String one);
}
 
B

Ben Bacarisse

Qu?bec said:
Hi again sorry for the missing code, I thought it was too much. If you
never did JNI stay away, you may be scared :)

Fear not. Many of us have been about the block a few times. After IBM
jCL, nothing is really scary!
Anyway, now I am sure the for loops where good.

They are.

char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " <from a
friend on this group ...
"abcdefghijklmnopqrstuvwxyz_-";

This is a file-scope array object.
JNIEXPORT jstring JNICALL Java_Serial_numero
(JNIEnv *env, jobject jobjc, jstring jstr){
jboolean iscopy;
jstring ret;
jsize len;
int i, j;
const char *fmt;
char alphabet[65];

And this is an automatic (function-local) array object with the same
name. It "shadows" the one you correctly defined, effectively hiding
it. What's worse, it's uninitialised, so it may contain any old junk.

Just delete this line.

<snip>
 
B

Ben Bacarisse

Kenneth Brody said:
Ever try reading WhiteSpace source code from hardcopy?

No, but then I've never *had* to use either. It's a bit like hungry
polar bears -- not at all scary because I don't expect to be on an ice
floe any time soon!
 
P

Phil Carmody

Qu?bec said:
How comes the for loop just printf 3 characters?

1 e
7 e
10 e

The string mixed by C is : J?an Pi?rr?

=========
fmt string is "Jean Pierre"
---------------
const char *fmt;
....
strcpy(ligne, fmt);
...
for(i=0;i<11;i++){
for(j=0;j<65;j++){

65 is a magic number. It's not even self-evidently correct as it stands.
If you were to add another character to your alphabet, you'd need to change
this line too. If you're attempting to match names, then you'll definitely
need to change the alphabet, even if you're restricting yourself to ASCII
- have you never encountered someone with a '.' in their name, for example
(there's one on comp.lang.c), or even "'"?

Re-order, and use sizeof().

Phil
if(alphabet[j] == fmt){
ligne = alphabet[65-j];
printf("%d %c\n", i, fmt);
break;
}
}

}

===
char alphabet[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z', '_', '-'};

Pics or it didn't happen.
-- Tom (/. uid 822)
 
J

Joe Pfeiffer

Phil Carmody said:
65 is a magic number. It's not even self-evidently correct as it stands.
If you were to add another character to your alphabet, you'd need to change
this line too. If you're attempting to match names, then you'll definitely
need to change the alphabet, even if you're restricting yourself to ASCII
- have you never encountered someone with a '.' in their name, for example
(there's one on comp.lang.c), or even "'"?

Re-order, and use sizeof().

You raise a good point, but a bit of explanation is probably worth
while:

A number that appears in your code with no explanation, as if by magic,
is a "magic number" (the term comes from a number that was at the
beginning of an a.out file and identified the file as a.out and also
defined which of several "types" of a.out file it was. This number was
actually referred to as the "magic number").

There are at least two major problems with magic numbers:

1) They aren't documented. There is no way for someone reading the code
to see 65 and understand, in isolation, why the number is 65 and not
64 or 66. Yes, the reader can find the declaration of alphabet, count
the elements, and realize that 65 is the right number. That's
needlessly obscure.

2) They aren't self-correcting. You don't want the number 65, you want
the elements in the alphabet array. If you add an element, you need to
locate every single instance of 65 that refers to the number of elements
in that particular array and change it -- without changing any 65s that
refer to something else.

So, there's a pretty well-established rule that a magic number should
never appear in your code. There are a few numbers that appear so
frequently and whose meaning is so obvious that they are OK -- 0,
probably 1, maybe -1, outside chance of 2 -- but those are pretty much
the list.

Instead, anyplace you need a constant, you should derive it if
possible. As Phil says, sizeof(alphabet) is what you really want here.
In some cases, it's good to derive it in a #define, and use that
everywhere it appears.

If there is no way derive it, use a defined constant, like

#define WORD_SIZE 32

Then you can:

#define SIGN_BIT (1 << (WORD_SIZE-1))

Anecdote: my coding standards for my classes forbade magic numbers.
The student who turned in a program that included

#define TEN 10

was a bit irate when he got docked for a magic number....
 
I

Ike Naar

How comes the for loop just printf 3 characters?

1 e
7 e
10 e

The string mixed by C is : J?an Pi?rr?

=========
fmt string is "Jean Pierre"
---------------
const char *fmt;
....
strcpy(ligne, fmt);
...
for(i=0;i<11;i++){
for(j=0;j<65;j++){
if(alphabet[j] == fmt){
ligne = alphabet[65-j];
printf("%d %c\n", i, fmt);
break;
}
}

}

===
char alphabet[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z', '_', '-'};


In addition to the problems reported by others, there's a subtle
bug in your program: the line

ligne = alphabet[65-j];

has undefined behaviour when j equals 0 (which can happen if fmt
contains the character '0'). You probably want

ligne = alphabet[65-j-1];

or, getting rid of the magic number,

ligne = alphabet[sizeof alphabet - j - 1];
 
N

Nick Keighley

Phil Carmody said:
65 is a magic number. [...]

You raise a good point, but a bit of explanation is probably worth
while:

A number that appears in your code with no explanation, as if by magic,
is a "magic number" (the term comes from a number that was at the
beginning of an a.out file and identified the file as a.out and also
defined which of several "types" of a.out file it was.  This number was
actually referred to as the "magic number").

I'm pretty sure the term preceeds this unix usage. I suspect unix
called it that because of earlier usage.

For instance the term was apparently in use in the 1960s for the use
of arbitary constants in FORTRAN and COBOL programs.

<snip>
 
B

Ben Bacarisse

Joe Pfeiffer said:
A number that appears in your code with no explanation, as if by magic,
is a "magic number"
If there is no way derive it, use a defined constant, like

#define WORD_SIZE 32

Then you can:

#define SIGN_BIT (1 << (WORD_SIZE-1))

This is undefined but, of course, it may work. I point it out only in
case some beginners take that as a portable and reliable way to get the
sign bit. I think

#define SIGN_BIT (~INT_MAX)

is bound to work on all conforming C implementations.

<snip>
 
J

Jens Gustedt

Am 02/25/2012 11:30 AM, schrieb Shao Miller:
Can that produce a "negative zero"? C99 6.2.6.2p4.

yes, for sign and magnitude if the implementation doesn't have negative
zeros, the behavior would be undefined

do such beasts exist?

Jens
 
B

Ben Bacarisse

Jens Gustedt said:
Am 02/25/2012 11:30 AM, schrieb Shao Miller:

yes, for sign and magnitude if the implementation doesn't have negative
zeros, the behavior would be undefined

Yes, but in a sense that undefined behaviour doesn't matter as much as
it usually does! On a sign and magnitude machine which does not support
negative zero (i.e. where generating 1000...000 is UB) the problem can't
be solved.

But I agree I should have said "on all conforming C implementations
where it's possible to do what is required".

<snip>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top