Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   for loop skips items (http://www.velocityreviews.com/forums/t868356-for-loop-skips-items.html)

Qu?bec 02-15-2012 08:04 PM

for loop skips items
 
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[i]){
ligne[i] = alphabet[65-j];
printf("%d %c\n", i, fmt[i]);
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', '_', '-'};

Joe Pfeiffer 02-15-2012 08:32 PM

Re: for loop skips items
 
Qu?bec <once@was.enough.invalid> writes:

> 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[i]){
printf("%d %c\n", i, fmt[i]);
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$

Qu?bec 02-15-2012 08:42 PM

Re: for loop skips items
 
On Wed, 15 Feb 2012 13:32:02 -0700, Joe Pfeiffer wrote:
> Qu?bec <once@was.enough.invalid> writes:
>
>> 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[i]){
> printf("%d %c\n", i, fmt[i]);
> 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[i]- e -80- Ï
fmt[i]- e -80- Ï
fmt[i]- e -80- Ï
fmt[i]- 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[i]){
printf("fmt[i]- %c ", fmt[i]);
ligne[i] = alphabet[65-j];
printf("%d- %c\n",ligne[i]);
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);
}

Ben Bacarisse 02-15-2012 09:50 PM

Re: for loop skips items
 
Qu?bec <once@was.enough.invalid> writes:
<snip>
> 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.

<snip>
> 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>
--
Ben.

Noob 02-16-2012 09:49 AM

Re: for loop skips items
 
Ben Bacarisse wrote:

> Fear not. Many of us have been about the block a few times.
> After IBM jCL, nothing is really scary!


Not even http://en.wikipedia.org/wiki/Brain**** ?

Ben Bacarisse 02-17-2012 01:26 AM

Re: for loop skips items
 
Kenneth Brody <kenbrody@spamcop.net> writes:

> On 2/16/2012 4:49 AM, Noob wrote:
>> Ben Bacarisse wrote:
>>
>>> Fear not. Many of us have been about the block a few times.
>>> After IBM jCL, nothing is really scary!

>>
>> Not even http://en.wikipedia.org/wiki/Brain**** ?

>
> 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!

--
Ben.

Phil Carmody 02-22-2012 01:35 AM

Re: for loop skips items
 
Qu?bec <once@was.enough.invalid> writes:
> 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[i]){
> ligne[i] = alphabet[65-j];
> printf("%d %c\n", i, fmt[i]);
> 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', '_', '-'};


--
> I'd argue that there is much evidence for the existence of a God.

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

Joe Pfeiffer 02-22-2012 04:43 AM

Re: for loop skips items
 
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:

> Qu?bec <once@was.enough.invalid> writes:
>> 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().


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....

Ike Naar 02-22-2012 08:04 AM

Re: for loop skips items
 
On 2012-02-15, Qu?bec <once@was.enough.invalid> wrote:
> 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[i]){
> ligne[i] = alphabet[65-j];
> printf("%d %c\n", i, fmt[i]);
> 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[i] = alphabet[65-j];

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

ligne[i] = alphabet[65-j-1];

or, getting rid of the magic number,

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

Nick Keighley 02-22-2012 08:19 AM

Re: for loop skips items
 
On Feb 22, 4:43*am, Joe Pfeiffer <pfeif...@cs.nmsu.edu> wrote:
> Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes:
> > Qu?bec <o...@was.enough.invalid> writes:


> > 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>


All times are GMT. The time now is 02:52 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.