log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- Latest hardware upgrade from RISCOSbits (News:)
- WROCC November 2024 talk o...ay - Andrew Rawnsley (ROD) (News:2)
- October 2024 News Summary (News:3)
- RISC OS London Show Report 2024 (News:1)
- RISC OS London Show 2024 - pictures (News:2)
- RISC OS London Show 2024 - Notes from the talks (News:)
- RPCEmu 0.9.5 (Gen:2)
- Late breaking news from RISCOSbits (News:)
- ROD updates RISC OS Direct release (News:)
- What will R-Comp be showing N.Ex.T? (News:)
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
 
View on Mastodon
@www.iconbar.com@rss-parrot.net
Site Search
 
Article archives
The Icon Bar: Programming: C programming problem
 
  C programming problem
  Cauchy (21:58 25/8/2015)
  Cauchy (22:46 25/8/2015)
    helpful (02:50 26/8/2015)
      VincceH (08:56 26/8/2015)
        Phlamethrower (09:02 26/8/2015)
          VincceH (09:20 26/8/2015)
            arawnsley (09:51 26/8/2015)
              VincceH (17:04 26/8/2015)
        Cauchy (13:23 26/8/2015)
 
John O'Meara Message #123700, posted by Cauchy at 21:58, 25/8/2015
Member
Posts: 43
The following is not working.
int main(void)
{
int number; short i = 0; char ch;
char str[80];

printf("enter a number: ");
do {
ch = getchar();
str[i] = ch;
i++;
} while(ch != '\n' && !isalpha(ch));
number = atoi(str);

if(!isalpha(number))
printf("integer is: %d", number);
}
If I enter a 2 or 3 digit number like 123 it works ok, i.e., the last statement prints out;
integer is: 123, but if I enter a 4 or 5 digit number like 1234, the last statement of the code is skipped as if 'number' was an alphabelical character. I don't understand what is happening with the last if in the code. I compile it using Acorn's C/C++ C compiler. Does any have any ideas. Thanks in advance.
  ^[ Log in to reply ]
 
John O'Meara Message #123701, posted by Cauchy at 22:46, 25/8/2015, in reply to message #123700
Member
Posts: 43
Sorry to bother ye. It works with the gcc compiler; it must be a bug in Acorn's C/C++ compiler. Thanks.
  ^[ Log in to reply ]
 
Bryan Hogan Message #123702, posted by helpful at 02:50, 26/8/2015, in reply to message #123701
Member
Posts: 254
OK, I'm not a C programmer, but surely isalpha(number) makes no sense? It is only designed to say whether a single character (0-255) is an alphabetic one, so passing it a large number is going to have undefined results.

(cue regular C programmers to point out how I've misunderstood things!)
  ^[ Log in to reply ]
 
VinceH Message #123703, posted by VincceH at 08:56, 26/8/2015, in reply to message #123702
VincceH
Lowering the tone since the dawn of time

Posts: 1600
No, you're right - that's what it is.

It'll return true if the value passed is equivalent to an alphabetical character.

The first use of it in that example program - the condition in the do...while loop is fine, because that's checking the character entered (albeit that checking at that point is flawed - see below).

The second use, though, is checking the number - which may or may not be equivalent to an alphabetic character. isalpha() takes an int as its argument, which means you can pass larger values - as is the case here - but when you do I think its behaviour is undefined, so it's not surprising that GCC and Norcroft exhibit different behaviour.

Bottom line, though: it's not a bug in Norcroft.

Addressing the OP now.

You're building a number based on keyboard input, but by checking that the character is not an alphabetical one, you're still allowing other characters like ',.[]# etc to be input. Also, that check being part of the loop is wrong.

I'd suggest a better solution would be to check that the input character is between 48 and 57 before appending it to the string. (Since you're converting the string to an int, decimals are obviously irrelevant, so no need to look for '.')

Therefore, something like:


int main(void)
{
int number, ix=0;
char ch, txinput[10];

printf("Enter a number: ");

do
{
ch=getchar();
if( (ch>=48) && (ch<=57)) txinput[ix++] = ch;
} while( (ch!='\n') && (ix<10) )

number=atoi(txinput);
printf("Integer is %d",number);
}


Now, we're checking that the input character is 0-9 before appending it to the string - so the isalpha(..) in the while() is gone.

Also, note the additional check I've put in place in the do..while loop: That the number of digits the user inputs doesn't exceed the number of bytes assigned to the string being built up.

What should happen only the characters 0-9 are added to the string; anything else is ignored - except a hit on return. The loop will end if return is pressed - or if the user has input 10 digits.

The string isn't checked before being passed to atoi() because of how it's been built up - butin real world code, you might want to add suitable checks at that point as well. You can never be too careful!

(Final note: I typed this version from memory of the original because I was too lazy to copy and paste it into my reply for editing - so things like variables may not be the same. It can probably be greatly improved, but I tried to keep it as close to what I think the original was to make it more obvious to the OP)

[Edited by VincceH at 09:58, 26/8/2015]

[Edited by VincceH at 10:00, 26/8/2015]
  ^[ Log in to reply ]
 
Jeffrey Lee Message #123704, posted by Phlamethrower at 09:02, 26/8/2015, in reply to message #123703
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
I'd suggest a better solution would be to check that the input character is between 48 and 57 before appending it to the string. (Since you're converting the string to an int, decimals are obviously irrelevant, so no need to look for '.')
A more 'correct' way of doing that would be to use the isdigit() function, so that it will cope with non-ASCII systems.

But since you're highly unlikely to run it on a non-ASCII system you can probably just go for the simple range check.
  ^[ Log in to reply ]
 
VinceH Message #123705, posted by VincceH at 09:20, 26/8/2015, in reply to message #123704
VincceH
Lowering the tone since the dawn of time

Posts: 1600
I didn't know there even was an isdigit() function - but it makes sense if there's an isalpha() one!
  ^[ Log in to reply ]
 
Andrew Rawnsley Message #123706, posted by arawnsley at 09:51, 26/8/2015, in reply to message #123705
R-Comp chap
Posts: 600
The method of building the string also looks a bit "off" to me. Writing directly to a char array won't null-terminate the string, so isn't there a risk of corruption coming in that way?

The source string isn't even initialised NULL, so I'd imagine there could be any old rubbish in RAM.
  ^[ Log in to reply ]
 
John O'Meara Message #123707, posted by Cauchy at 13:23, 26/8/2015, in reply to message #123703
Member
Posts: 43
Thanks for the reply, ye are correct the whole thing was written incorectly, there is no bug in Acorn's C/C++ compiler, it is just a mistake I made in what I was trying to do. Thanks very much. I only use C on an on and off basis and more off than on at that. Thanks again.
  ^[ Log in to reply ]
 
VinceH Message #123708, posted by VincceH at 17:04, 26/8/2015, in reply to message #123706
VincceH
Lowering the tone since the dawn of time

Posts: 1600
The method of building the string also looks a bit "off" to me.
Yes, well spotted. After exiting the loop, writing a null to the index position (which was being updated after each digit was added) in the character array will cover both those.

(Sorry, quickly hit reply without looking at the variable names...)
  ^[ Log in to reply ]
 

The Icon Bar: Programming: C programming problem