Convert VB code to C code.

  • Thread starter Kenneth Osenbroch
  • Start date
K

Kenneth Osenbroch

Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.

Thanks,
Kenneth
 
D

Dave Vandervies

Hmm. Interesting, yet oddly not inappropriate, crosspost list on
this one.

Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like,

You'll want to get a textbook (or somebody who knows C) for this.
Get a basic knowledge of the language, and *then* start translating code
into it.

Be careful choosing textbooks, because there are a lot of bad ones
out there. One of the best, especially if you've done some programming
in other languages, is _The C Programming Language, 2nd edition_ by
Kernighan and Ritchie.

and how "Val(Mid.." and "Right(Str..." are
translated into C.

If I'm remembering my misspent youth with the Commodore 64 correctly,
and if VB has inherited them (from there or from a common source) without
too many changes (or if my misremembering and VB's embrace-and-extend have
modified them in similar ways), Val converts a string into a numeric value
and Right takes the last N characters of a string. (The code snippet here
also uses Mid, which takes a substring out of the middle of a string.)

If that's incorrect, I'm sure we'll be hearing about it from somebody
in the VB newsgroup.

Look up sscanf for converting strings into numeric values.

Strings in C are just arrays of characters, so you can handle substring
operations by copying the appropriate set of characters into another
buffer and terminating it appropriately. Be careful with what goes
where; you need to do all the memory management yourself, which bites
people coming from Basic-ish backgrounds with great predictability.


dave
 
C

CBFalconer

Kenneth said:
I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's
FOR loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.

Here in c.l.c we have no idea what those functions do. However I
can give you a C equivalent of the for statement:

for (iCounter = Len(...); /* initialization */
iCounter >= 1; /* continue condition */
iCounter--) /* loop alteration action */
{
/* whatever that funny statement does */
}

but lose the ugly hungarian notation.
 
C

cr88192

Kenneth Osenbroch said:
Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.

I think (mind you c's arrays are 0 based, and I don't know vb):
for(iCounter=strlen(sReference); iCounter>0; iCounter--)
iSum+=atoi(sReference[i-1])*iMultiplier;

//buf is added here as a string buffer
sprintf(buf, "%d", 10-(iSum%10));
fReferenceChecksum=atoi(buf[strlen(buf)-1]);

this is just a guess (I would think the last one would have suffered from a
type error, but afaik vb can also insert implicit coercions).
 
C

cr88192

cr88192 said:
Kenneth Osenbroch said:
Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.

I think (mind you c's arrays are 0 based, and I don't know vb):
for(iCounter=strlen(sReference); iCounter>0; iCounter--)
iSum+=atoi(sReference[i-1])*iMultiplier;

//buf is added here as a string buffer
sprintf(buf, "%d", 10-(iSum%10));
fReferenceChecksum=atoi(buf[strlen(buf)-1]);
and, in being distracted, made an obvious error:
fReferenceChecksum=atoi(&buf[strlen(buf)-1]);

or:
fReferenceChecksum=atoi(buf+(strlen(buf)-1));
 
F

Frank Adam

Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.
Kenneth, i didn't know that you didn't know about C. I thought you
didn't know about VB, but now i just don't know which one you don't
know about ? ;-p

Perhaps my using a pointer to iterate through the string, threw you ?
Although, on reread, i was going through the string forward, not
backwards, so that may have played some part if it didn't work, or
maybe i was just plain cold sober.. but TBH, i did expect that you can
adjust that code as needed.

What exactly is this for ? Is this a school project, or do you want it
to just get the VB code to work in C ?
If it's just a conversion, then lose the iterator and the for-next and
use a pointer to go through the string. It's much cleaner.

Anyway, the "for-next" in C is :
for( counter = start; counter > 1; counter--)
where 'start' in your case would be strlen(sReference) or in VB
Len(sReference).

Val(string) in VB returns the numeric value of a String. ie: "48"
yields 48 as a value, not to be confused with Ascii 48 which is 0. :)
In C, you can do that with atoi(buffer).
value = atoi(buffer);

Mid(buffer, start, length) picks out 'length' number of characters
from 'buffer', starting at 'start'
In C, that can be done with strncpy(), sprintf() etc...

It could be made up like this :

char* mid(buffer, start, len)
{
char *p, *ret;
if (NULL != buffer)
{
/* should check for len and start being ok..but bugger it */
p = &buffer[start];
ret = malloc(sizeof(char) * len + 1);
if (NULL != ret)
{
strcnpy(ret,p,len);
ret[len] = '\0' /* don't remember if it terms or not */
}
}
return ret;
}


Right$(buffer, length) returns the rightmost 'length' characters from
'buffer'.
A C version may be :

char* Right(char* buffer,long len)
{
char* p = buffer, long blen;

if(NULL != p)
{
blen = strlen(p);
if (len < strlen(p))
p = &buffer[blen - len];
}
return p;
}
 
F

Frank Adam

char* mid(buffer, start, len)
This should have read :
char* mid(char* buffer, size_t start, size_t len)
char* Right(char* buffer,long len)
And this being x-posted to C.L.C. i should have remembered to use
size_t instead of longs. I'm slapping my hands as we speak.. :)
 
R

Richard Bos

I think (mind you c's arrays are 0 based, and I don't know vb):
for(iCounter=strlen(sReference); iCounter>0; iCounter--)
iSum+=atoi(sReference[i-1])*iMultiplier;

Several mistakes here.

First of all, atoi() is not the function of choice. If sReference
contains an value which isn't representable in int, it causes undefined
behaviour. Use strtol() instead; it doesn't have this problem, and is
more flexible, too. For example, it can be used to detect errors which
the Basic code doesn't even check for.

Second, note that the length parameter to both Mid() and Right() is 1,
meaning that the Basic code handles single characters. This makes the C
equivalent simpler than one would expect:

for (counter = strlen(sReference)-1; counter>=0; counter--)
iSum += (sReference[counter]-'0') * iMultiplier;

Note: no function calls except strlen(). Neither atoi() nor strtol() is
even necessary. And since all members of the string are worth the same
amount and their order doesn't matter, even strlen() can be eliminated:

for (counter=0; sReference[counter]; counter++)
iSum += (sReference[counter]-'0') * iMultiplier;

Of course, the equivalent using pointers is just as valid.

[ Next line copied here for easier reference ]
//buf is added here as a string buffer
sprintf(buf, "%d", 10-(iSum%10));
fReferenceChecksum=atoi(buf[strlen(buf)-1]);

The extra buffer is unnecessary. Note, again, the single character used
to determine the end result. (Also, your version results in an int,
while the Basic code gives a one-character string.)

fReferenceCheckSum = 10-iSum%10 + '0';

That simple. Unless you want a string instead of a single char, in which
case fReferenceCheckSum (what _is_ it with M$ programmers and
sesquipedalian identifiers, anyway?) needs to be at least a char[2], not
a char, and you need to write

fReferenceCheckSum[0]=10-iSum%10 + '0';
fReferenceCheckSum[1]='\0';

Richard
 
C

cr88192

Richard Bos said:
I think (mind you c's arrays are 0 based, and I don't know vb):
for(iCounter=strlen(sReference); iCounter>0; iCounter--)
iSum+=atoi(sReference[i-1])*iMultiplier;

Several mistakes here.
yes, it seems there were a lot.
in my distraction of trying to understand the original code, it seems I
forgot, eg, how to use strings, or much else for that matter...

those fragments are emberassing, they make me look like some stupid
newbie...
First of all, atoi() is not the function of choice. If sReference
contains an value which isn't representable in int, it causes undefined
behaviour. Use strtol() instead; it doesn't have this problem, and is
more flexible, too. For example, it can be used to detect errors which
the Basic code doesn't even check for.
I usually use my own version as the standard version, eg, has problems
dealing with things like '0x...' in many cases.
Second, note that the length parameter to both Mid() and Right() is 1,
meaning that the Basic code handles single characters. This makes the C
equivalent simpler than one would expect:

for (counter = strlen(sReference)-1; counter>=0; counter--)
iSum += (sReference[counter]-'0') * iMultiplier;
one could do that...
Note: no function calls except strlen(). Neither atoi() nor strtol() is
even necessary. And since all members of the string are worth the same
amount and their order doesn't matter, even strlen() can be eliminated:

for (counter=0; sReference[counter]; counter++)
iSum += (sReference[counter]-'0') * iMultiplier;
yes, possible.
however, in this case the op may no longer recognize the algo?...
Of course, the equivalent using pointers is just as valid.
agreed.

[ Next line copied here for easier reference ]
//buf is added here as a string buffer
sprintf(buf, "%d", 10-(iSum%10));
fReferenceChecksum=atoi(buf[strlen(buf)-1]);

The extra buffer is unnecessary. Note, again, the single character used
to determine the end result. (Also, your version results in an int,
while the Basic code gives a one-character string.)
yes, I had failed to take into account that printing a value 0..9 in decimal
and taking the last digit is equivalent to just using the value.
fReferenceCheckSum = 10-iSum%10 + '0';
I was confused as to what was going on with that...
of course, this looks dubious as well.
That simple. Unless you want a string instead of a single char, in which
case fReferenceCheckSum (what _is_ it with M$ programmers and
sesquipedalian identifiers, anyway?) needs to be at least a char[2], not
a char, and you need to write

fReferenceCheckSum[0]=10-iSum%10 + '0';
fReferenceCheckSum[1]='\0';
dunno, 'f' makes me think 'float', but I don't know what type the op was
using...
 
A

Alex Fraser

Richard Bos said:
[ Next line copied here for easier reference ]
fReferenceCheckSum = 10-iSum%10 + '0';

This is not equivalent if iSum % 10 is zero (produces '0' + 10 instead of
'0'). Instead:

fReferenceCheckSum = (10 - iSum % 10) % 10 + '0';

Perhaps better, put a "% 10" inside the loop instead of the first one above
and almost arbitrary length "number strings" (I guess: barcodes) will work.

Alex
 
A

anony*mouse

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone?

Code:
#include <stdio.h>
#include <ctype.h>

int main(void)
{
  const char* sReference  = "12dgh3456";
  const int   iMultiplier = 11;

  float fReferenceCheckSum;
  int   iSum     = 0;
  int   iCounter = strlen(sReference);

  while (--iCounter >= 0)
  {
    iSum += isdigit(sReference[iCounter]) ? 
              (sReference[iCounter] - '0') * iMultiplier : 0;
  }

  fReferenceCheckSum = (float) ((10 - (iSum % 10)) % 10);

  printf("fReferenceCheckSum = %.0f, iSum = %d",
              fReferenceCheckSum, iSum);

  getchar();
  return 0;
}
 
M

MJSR

cr88192 said:
[ Next line copied here for easier reference ]
//buf is added here as a string buffer
sprintf(buf, "%d", 10-(iSum%10));
fReferenceChecksum=atoi(buf[strlen(buf)-1]);

The extra buffer is unnecessary. Note, again, the single character used
to determine the end result. (Also, your version results in an int,
while the Basic code gives a one-character string.)

fReferenceCheckSum = 10-iSum%10 + '0';

Somebody has already pointed out that this would be wrong if
iSum%10 is zero. One would have to examine the declaration of
fReferenceCheckSum (or its later usage) to determine the correct
C; strings are automatically converted to numbers in VB (at least,
in my experience) and characters are represented as strings with
length one. So
fReferenceCheckSum = (10-iSum%10)%10;
would be correct if fReferenceCheckSum is a numeric variable.
 
J

John Smith

Kenneth said:
Hi,

I am having trouble translating the following lines of Visual Basic
code to C.

For iCounter = Len(sReference) To 1 Step -1
iSum = iSum + Val(Mid(sReference, iCounter, 1)) * iMultiplier
Next

fReferenceCheckSum = Right(Str(10 - (iSum Mod 10)), 1)

Any ideas anyone? I have had some help, but I need to know how C's FOR
loops looks like, and how "Val(Mid.." and "Right(Str..." are
translated into C. Any further help would be greatly appreciated.

Thanks,
Kenneth

Standard C library doesn't have a function comparable to VB's mid(),
left() and right(). Here is a homegrown C function similar to mid():

/* midstr returns a substring of n
characters of str starting at s,
or remaining characters of string
if s+n exceeds the length of str.
*/
char* midstr(char* str, int s, int n)
{
int idx, jdx, len;
char* mid;

jdx = 0;
len = 0;
while(str[jdx++] != '\0')
++len;
if(s + n > len)
n = len - s;
jdx = 0;
mid = malloc(n+1 * sizeof(*mid));
if(mid == NULL)
{
fprintf(stderr, "malloc failed in midstr()\n");
exit(EXIT_FAILURE);
}
for(idx = s; idx < s+n; ++idx)
mid[jdx++] = str[idx];
mid[n] = '\0';

return mid;
}
(Disclaimer: this could undoubtedly be made more efficient by a more
clever programmer than myself.)

Numeric strings can be converted to a number with any of several Std C
library functions. You need to do some reading about how C handles
strings. It's very different than in VB. C doesn't have a "string" type.
Essentially, strings in C are arrays of characters, terminated with a
NULL character.

C's for loops look like this (a simple example; it can get more
complicated):

for(i=0; i<20; i++)
{
/* code here */
}

This is equivalent to VB:

for i = 0 to 19
'code here
next i

where a step value of 1 is implicit.

-JS
 
R

Richard Bos

John Smith said:
Essentially, strings in C are arrays of characters, terminated with a
NULL character.

_Null_ character, please. Case is important. NULL is a macro expanding
to a null pointer constant, not a character. (void *)0 is hardly a good
string terminator, let alone '(void *)0'.

Richard
 
P

pete

Richard said:
_Null_ character, please. Case is important.

or "null character",
since it's not at the begining of a sentence.
NULL is a macro expanding
to a null pointer constant, not a character.

.... and a null pointer is a pointer
that compares equal to a null pointer constant.
 
S

Sebastian Kaliszewski

Richard said:
_Null_ character, please. Case is important. NULL is a macro expanding
to a null pointer constant, not a character. (void *)0 is hardly a good
string terminator, let alone '(void *)0'.

Well, according to standard NULL should expand to 0. (void*)0 is not
conformant IMHO (some pre C89 compilers did so)

rgds
Sebastian
 
R

Richard Bos

Sebastian Kaliszewski said:
Well, according to standard NULL should expand to 0. (void*)0 is not
conformant IMHO

Ahem. Neither your humble nor my arrogant opinion are worth what the cat
dragged in; it is the Standard which defines C, not our opinion. And the
Standard says:

7.17#3:
# 3 The macros are
# NULL
# which expands to an implementation-defined null pointer constant;

6.3.2.3#3:
# 3 An integer constant expression with the value 0, or such an
# expression cast to type void *, is called a null pointer constant.

0 is an integer constant expression with the valud 0; (void *)0 is such
an expression cast to type void *; it is, therefore, a null pointer
constant; and because of that, it is a valid expansion of NULL.
(some pre C89 compilers did so)

There was no such thing as void, pre-C89. IIRC the Standard Committee
nicked it from C++.

Richard
 
P

pete

Sebastian said:
Well, according to standard NULL should expand to 0. (void*)0 is not
conformant IMHO (some pre C89 compilers did so)

What standard would that be?

N869
7.17 Common definitions <stddef.h>
[#3] The macros are
NULL
which expands to an implementation-defined null pointer
constant;
6.3.2.3 Pointers
[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.



C89 last public draft
4.1.5 Common definitions <stddef.h>
The macros are
NULL
which expands to an implementation-defined null pointer constant;
3.2.2.3 Pointers
An integral constant expression with the value 0, or such an
expression cast to type void * , is called a null pointer constant.
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top