473,748 Members | 2,294 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Please comment on my program

I'm a newbie and have attempted to create a program to convert a string
containing the representation of a number in a specified base to a
decimal integer. Here's the code:

#include <stdio.h>

unsigned todecimal( char *s, int base)
{
unsigned num = 0, mul;
int len=0;
while (*++s != '\0')
++len;
--s;
for (mul=1; len>=0; --len, mul*=base, --s)
{
if (*s >= '0' && *s <= '9')
num+= (*s-'0')*mul;
else if (*s>='A'&& *s<='Z')
num+= (*s-'A'+10)*mul;
else if (*s>='a' && *s<='z')
num+=(*s-'a'+10)*mul;
}
return num;
}

int main()
{
char s[33];
int base;
printf("Enter the number and its base: ");
scanf("%s%d",s, &base);
printf("Decimal value = %u\n", todecimal(s, base) );
return 0;
}

Sep 25 '06 #1
5 1632
Registered User wrote:
>
I'm a newbie and have attempted to create a program to convert a
string containing the representation of a number in a specified
base to a decimal integer. Here's the code:

#include <stdio.h>

unsigned todecimal( char *s, int base)
{
unsigned num = 0, mul;
int len=0;
while (*++s != '\0')
++len;
--s;
for (mul=1; len>=0; --len, mul*=base, --s)
{
if (*s >= '0' && *s <= '9')
num+= (*s-'0')*mul;
else if (*s>='A'&& *s<='Z')
num+= (*s-'A'+10)*mul;
else if (*s>='a' && *s<='z')
num+=(*s-'a'+10)*mul;
}
return num;
}

int main()
{
char s[33];
int base;
printf("Enter the number and its base: ");
scanf("%s%d",s, &base);
printf("Decimal value = %u\n", todecimal(s, base) );
return 0;
}
Shows promise, but here are some things to consider:

There is no guarantee that the letters 'A'..'Z' are contiguous.
Same for 'a'..'z'. See EBCDIC encoding for one example.

Nothing stops your conversion if an input 'digit' is beyond the
size allowed by base.

Nothing detects overflow.

--
Some informative links:
<news:news.anno unce.newusers
<http://www.geocities.c om/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html >
<http://www.netmeister. org/news/learn2quote.htm l>
<http://cfaj.freeshell. org/google/>

Sep 25 '06 #2
Registered User schrieb:
I'm a newbie and have attempted to create a program to convert a string
containing the representation of a number in a specified base to a
decimal integer. Here's the code:

#include <stdio.h>

unsigned todecimal( char *s, int base)
"to" followed by a lower case letter belongs as an identifier
to the implementation; i.e. this name might at some time clash
with something the standard library provides.

You do not modify the passed string, so you may as well pass a
const char *.

Something to document early: You check neither s!=NULL nor
2<=base<=36. If the user does not find this, you may get
invalid input and the ensuing crash or returned garbage is
somehow _your_ fault...
{
unsigned num = 0, mul;
Note: I'd rather use unsigned long which is the widest unsigned
integer type in C89 (or unsigned long long for C99).
int len=0;
while (*++s != '\0')
If s is "", then you run off wildly through storage that does
not necessarily belong to you. In addition, you modify a
parameter -- it may be a better idea to create a copy and modify
that.
Either stick with strlen() or amend this to
const char *tmp;
for (tmp = s; *tmp != '\0'; ++tmp) {
++len;
}
++len;
--s;
for (mul=1; len>=0; --len, mul*=base, --s)
{
if (*s >= '0' && *s <= '9')
num+= (*s-'0')*mul;
else if (*s>='A'&& *s<='Z')
num+= (*s-'A'+10)*mul;
else if (*s>='a' && *s<='z')
num+=(*s-'a'+10)*mul;
This breaks if 'Z'-'A' != 25...
A better method is using a digits array:
char digits[] = "0123456789abcd efghijklmnopqrs tuvwxyz";
and set the allowed range:
digits[base] = '\0';
and then find the digit using strchr()
char *occurred = strchr(digits, tolower(*s));
if (occurred && *occurred) {
int digit = occurred - s;
....
The other thing is that you do not make sure that you have
no overflow: For num of type unsigned int, this means:
unsigned int add;

if (UINT_MAX / digit < mul) {
/* mul will become too large in the next step and is
* already too large for digit*mul to be representable */
/* Your error handling here */
}
add = digit * mul;
if (UINT_MAX - add < num) {
/* mul will become too large in the next step and is
* already too large for num+digit*mul to be representable */
/* Your error handling here */
}

}
return num;
}
You omitted error handling; there are several types of errors, so
you should decide how you want to flag "everything okay" vs. "something
bad happened".
Bad things that could happen:
s == NULL
base < 2
base strlen(digits)
one of the characters not in digits (where digits[base] == 0)
overflow
Should everything be flagged differently?
How do you want to flag this?
As you have unsigned int values, the obvious candidate for an error
return is UINT_MAX. Alternatively, you can have a look at the
strtoul() function and how it flags "bad" values.
int main()
int main (void)
-- we have that much time.
{
char s[33];
int base;
printf("Enter the number and its base: ");
scanf("%s%d",s, &base);
Always make sure that you did get what you expected when using
*scanf():
if (2 != scanf("%s%d", s, &base)) {
/* Your error handling here */
}
printf("Decimal value = %u\n", todecimal(s, base) );
return 0;
}
Note: As you have an excellent alternate version (strtoul()), you
can test your function in comparison with strtoul(). Maybe you have
to wrap strtoul() to get the same outward behaviour.
When testing, do not forget corner cases such as:
s = NULL, s = ""
base = -1, base = 0, base = 1, base = 2, base = 36, base = 37
s = "/", s = "-1", s = "3" for base = 2, s = "0",
s = string holding UINT_MAX, s = string holding UINT_MAX + 1, ....
Cheers

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 25 '06 #3
Registered User posted:
#include <stdio.h>

unsigned todecimal( char *s, int base)

Take that argument as a pointer to const. I would also suggest making the
actual arguments themselves const.

{
unsigned num = 0, mul;
int len=0;

I would advocate the use of an unsigned integer type for "len".

>
while (*++s != '\0')
++len;
--s;

Highly inefficient on most systems; you'd probably be better off with
something like:

size_t len = strlen(s);

s += len-1;

for (mul=1; len>=0; --len, mul*=base, --s)

If using an unsigned type, change the conditional to: len != -1

{
if (*s >= '0' && *s <= '9')
num+= (*s-'0')*mul;
else if (*s>='A'&& *s<='Z')
num+= (*s-'A'+10)*mul;
else if (*s>='a' && *s<='z')
num+=(*s-'a'+10)*mul;

As mentioned elsethread, the codes for the letters of the alphabet aren't
necessarily in order one after the other.

--

Frederick Gotham
Sep 25 '06 #4
On Mon, 25 Sep 2006 10:42:47 -0400, CBFalconer <cb********@yah oo.com>
wrote:
>Registered User wrote:
>>
I'm a newbie and have attempted to create a program to convert a
string containing the representation of a number in a specified
base to a decimal integer. Here's the code:

#include <stdio.h>

unsigned todecimal( char *s, int base)
{
unsigned num = 0, mul;
int len=0;
while (*++s != '\0')
++len;
--s;
for (mul=1; len>=0; --len, mul*=base, --s)
{
if (*s >= '0' && *s <= '9')
num+= (*s-'0')*mul;
else if (*s>='A'&& *s<='Z')
num+= (*s-'A'+10)*mul;
else if (*s>='a' && *s<='z')
num+=(*s-'a'+10)*mul;
}
return num;
}

int main()
{
char s[33];
int base;
printf("Enter the number and its base: ");
scanf("%s%d",s, &base);
printf("Decimal value = %u\n", todecimal(s, base) );
return 0;
}

Shows promise, but here are some things to consider:

There is no guarantee that the letters 'A'..'Z' are contiguous.
Same for 'a'..'z'. See EBCDIC encoding for one example.
While it's important to understand that the C Standard does not
guarantee that the character set used to encode 'A'..'Z' or 'a'..'z'
is not contiguous, it's also important to realize that source code
distributed with a particular character encoding is inherently
non-portable. ZIP files containing source code encoded with the ASCII
character encoding are inherently non-portable. True pedantics would
note such a caveat.

Best regards
--
jay
Sep 26 '06 #5
[snip]
See snippet functions bascnvrt.c and ltostr.c:
http://c.snippets.org/browser.php

Sep 26 '06 #6

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

Similar topics

2
2378
by: rked | last post by:
I get nameSPAN1 is undefined when I place cursor in comments box.. <%@ LANGUAGE="VBScript" %> <% DIM ipAddress ipAddress=Request.Servervariables("REMOTE_HOST") %> <html> <head> <meta http-equiv="Content-Type" content="text/html;
13
3327
by: walter | last post by:
I wrote a program, and found one line of source code not compiled out. I rewrote it for simplicity as below. The comment in the program is big5 code text. --- my program --- main(){ int i, a; for (i=0;i<3;i++) a=0; // ÁקK³Q·j´M¦¨¥\ a=-1;
3
1735
by: hellfire | last post by:
Below is a pretty usless progam but being a begginer and working form a book i need some one to comment on it IE: is it set out right easy to follow i tried to use every thing i know to data your comments will be appricated thanks for your time /* VB1.C PROGRAM JUST TO MAKE DESISIONS */ #include<stdio.h> /* DECLARE VARIABLES */
2
1585
by: Sathyaish | last post by:
I am writing a program that will take a string that has a C source file and it would format all the multi-line comments like these: //Jingle bells, jingle bells, jingles all the way //O what fun it is to ride in a one-horse open sledge //yeah, jingle bells.... into
8
1687
by: G Patel | last post by:
I wrote the following program to remove C89 type comments from stdin and send it to stdout (as per exercise in K&R2) and it works but I was hoping more experienced programmer would critique the layout/style/etc. Any comments will be helpful. Thank you. /* **************************************************** C89/90 COMMENT REMOVER
6
1717
by: Clunixchit | last post by:
I would appreciate if you can criticise my code as well as if possible give advice on how to improve it. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <fcntl.h>
11
5064
by: garyusenet | last post by:
For this first time today I used the System.Diagnositcs namespace to launch a program from my c# code. The program launches OK but I have something which has completely stumped me. The SetWindowPos method does not work. If I run the code as it is presented below, app.exe launches in its own window and is displayed at the top left part of the screen. However it isn't repositioned which is what the last piece of code should do. HOWEVER if...
1
2345
by: Nethra | last post by:
Hi... I am trying a program which convert the multiline comment type in a program to single line comment type ie. /*have a nice day */ to //have a //nice day
10
1996
by: len | last post by:
I have created the following program to read a text file which happens to be a cobol filed definition. The program then outputs to a file what is essentially a file which is a list definition which I can later copy and past into a python program. I will eventually expand the program to also output an SQL script to create a SQL file in MySQL The program still need a little work, it does not handle the following items
0
8983
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9528
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9310
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9236
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8235
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4592
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4863
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2774
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2206
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.