(i'm french, sorry for my bad english)
I don't know how to get an int from a char[], the patern of the char will be the same everytime : "prendre 2", "prendre 44", "prendre 710"...
I want to check if the pattern of the sentence is correct and get the integer.
I have try to do this, but as you see, the problem is i just can check if the integer is between 0-9 because I check only one char.
[...]
else if (est_prendre(commande)){
/* if the output is 1*/
int number = commande[8]- '0'
}
int est_prendre(char *commande){
int i;
char temp[9] = "";
char c = commande[8];
int num = c - '0';
for (i=0; i<8; i++){
temp[i] = commande[i];
}
if (strcmp ("prendre ", temp) == 0)
{
if ( /* num IS INTEGER? */)
{
return 1;
}
else
{
return 0;
}
} else {
return 0;
}
}
I expect if commande = "prendre 3", output of est_prendre is 1 because the pattern is correct
And after than to put the integer into the variable number.
Thank You!
Assuming that 'commande + 8' is a valid substring, what you need is atoi() function (ASCII to Integer). This function is widely documented, and you can easily find online its usage.
int number = atoi(commande+8);
Just remember that the substring terminates at the first non-digit character:
atoi("23") returns 23
atoi("51hh37") returns 51
atoi("z3456") returns 0
Note: atoi converts input string into integer, and you can use it if you are sure it fits expected input. So, if you expect to have either long integers or float values in your string you can use atol() (ASCII to long) or atof() (ASCII to float).
This is very basic, you should (re)read any reference/tutorial on C that you have used to learn the language.
You should just use the sscanf() standard function:
int value;
if (sscanf(commande, "prendre %d", &value) == 1)
{
... it was a match, the variable 'value' will be set to the number from the string
}
you can delete the (strange-looking) code that copies characters from commande to temp, and the temp variable too of course. Just inspect the commande string directly.
Related
I'm working on an assignment and as part of it I need to extract the integer from a string.
I've tried using the atoi() function, but it always returns a 0, so then I switched up to strtol(), but it still returns a 0.
The goal is to extract the integers from the string and pass them as arguments to a different function. I'm using a function that then uses these values to update some data (update_stats).
Please keep in mind that I'm fairly new to programming in the C language, but this was my attempt:
void get_number (char str[]) {
char *end;
int num;
num = strtol(str, &end, 10);
update_stats(num);
num = strtol(end, &end, 10);
update_stats(num);
}
The purpose of this is in a string "e5 d8" (for example) I would extract the 5 and the 8 from that string.
The format of the string is always the same.
How can I do this?
strtol doesn't find a number in a string. It converts the number at the beginning of the string. (It does skip whitespace, but nothing else.)
If you need to find where a number starts, you can use something like:
const char* nump = strpbrk(str, "0123456789");
if (nump == NULL) /* No number, handle error*/
(man strpbrk)
If your numbers might be signed, you'll need something a bit more sophisticated. One way is to do the above and then back up one character if the previous character is -. But watch out for the beginning of the string:
if ( nump != str && nump[-1] == '-') --nump;
Just putting - into the strpbrk argument would produce false matches on input like non-numeric7.
If the format is always like this, then this could also work
#include <stdio.h>
int main()
{
char *str[] = {"a5 d8", "fe55 eec2", "a5 abc111"};
int num1, num2;
for (int i = 0; i < 3; i++) {
sscanf(str[i], "%*[^0-9]%d%*[^0-9]%d", &num1, &num2);
printf("num1: %d, num2: %d\n", num1, num2);
}
return 0;
}
Output
num1: 5, num2: 8
num1: 55, num2: 2
num1: 5, num2: 111
%[^0-9] will match any non digit character. By adding the * like this %*[^0-9] indicates that the data is to be read from the string, but ignored.
I suggest you write the logic on your own. I know, it's like reinventing the wheel, but in that case, you will have an insight into how the library functions actually work.
Here is a function I propose:
bool getNumber(str,num_ptr)
char* str;
long* num_ptr;
{
bool flag = false;
int i = 0;
*num_ptr = 0;
char ch = ' ';
while (ch != '\0') {
ch = *(str + i);
if (ch >= '0' && ch <= '9') {
*num_ptr = (*num_ptr) * 10 + (long)(ch - 48);
flag = true;
}
i++;
}
return flag;
}
Don't forget to pass a string with a \0 at the end :)
Given a string containing alphanumeric characters, calculate the sum of all numbers present in the string.
The problem with my code is that it displays the integers present before the characters, but it is not summing up the integers after the characters.
The execution is easy in python and C++ but I cant get it done using C! Can anyone please verify where I have done wrong? << thank you !
enter code here
#include<stdio.h>
#include<string.h>
int convert(char[]);
int main()
{
char ch[100],temp[100]={0};
int i=0,s=0,j=0,n;
scanf("%s",ch);
for(i=0;i<strlen(ch);i++)
{
if((ch[i]>='0') && (ch[i]<='9'))
{
temp[j]=ch[i];
j++;
}
else
{
if(temp[0]== '\0')
{
continue;
}
else
{
n=convert(temp);
s+=n;
temp[0]= '\0';
j=0;
}
}
}
printf("%d",s);
return 0;
}
int convert(char s[]) //converting string to integer
{
int n=0;
for(int i=0;i<strlen(s);i++)
{
n= n * 10 + s[i] - '0';
}
return n;
}
Input : 12abcd4
Expected output : 16
But the output is 12 for my code.
There are two problems in your code. The first was mentioned in the comments : if the last character is a digit, the last "number section" will not be taken into account. But I don't think that the solution given in the comments is good because if the last character is not a digit, you will have a wrong value. To correct this, I added an if statement that check if the last character is a digit, if so call convert().
The second problem is that strlen return the number of characters in you string from the beginning until it finds an '\0'. The way you used your string lead to the follow problem :
ch = "12abcd4".
At first you have temp = '1' + '2' + '\0'...
After calling convert() you set temp[0] to '\0', thus temp = '\0' + '2' + '\0'... .
And when you start reading digit again, you set '4' in temp[0]. Your string is now : '4' + '2' + '\0'... .
The n returned will be 42 and your result 54 (12+42). There are several solution to have the expected behavior, I chose to use your variable j to indicate how many characters should be read instead of using strlen() :
#include<stdio.h>
#include<string.h>
int convert(char[], int size);
int main() {
char ch[100],temp[100]={0};
int i=0,s=0,j=0,n;
scanf("%s",ch);
for(i=0;i<strlen(ch);i++) {
if((ch[i]>='0') && (ch[i]<='9')) {
temp[j]=ch[i];
j++;
// change here
if(i == strlen(ch) - 1) {
n=convert(temp, j);
s+=n;
}
}
else {
// change here
n=convert(temp, j);
s+=n;
if(temp[0]== '\0') {
continue;
}
temp[0]= '\0';
j=0;
}
}
printf("%d\n",s);
return 0;
}
//change here
int convert(char s[], int size) {
int n=0;
for(int i=0;i<size;i++) {
n= n * 10 + s[i] - '0';
}
return n;
}
You could use a combination of strtoul() and strpbrk() to do this.
Declare two character pointers start_ptr and end_ptr and make start_ptr point to the beginning of the string under consideration.
char *start_ptr=s, *end_ptr;
where s is the character array of size 100 holding the string.
Since your string has only alphanumeric characters, there is no - sign and hence there are no negative numbers. So we can get away with using unsigned integers.
We are using strtoul() from stdlib.h to perform the string to integer conversion. So let's declare two variables: rv for holding the value returned by strtoul() and sum to hold the sum of numbers.
unsigned long rv, sum_val=0;
Now use a loop:
for(; start_ptr!=NULL; )
{
rv = strtoul(start_ptr, &end_ptr, 10);
if(rv==ULONG_MAX && errno==ERANGE)
{
//out of range!
printf("\nOut of range.");
break;
}
else
{
printf("\n%lu", rv);
sum_val += rv;
start_ptr=strpbrk(end_ptr, "0123456789");
}
}
strtoul() will convert as much part of the string as possible and then make end_ptr point to the first character of the part of the string that could not be converted.
It will return ULONG_MAX if the number is too big and errno would be set to ERANGE.
Otherwise the converted number is returned.
strpbrk() would search for a set of characters (in this case the characters 0-9) and return a pointer to the first match. Otherwise NULL is returned.
Don't forget to include the following header files:
stdlib.h ---> strtoul
string.h ---> strpbrk
limits.h ---> ULONG_MAX
errno.h ---> errno
In short, we could make the program to something like
for(; start_ptr!=NULL; sum_val += rv, start_ptr=strpbrk(end_ptr, "0123456789"))
{
rv = strtoul(start_ptr, &end_ptr, 10);
if(rv==ULONG_MAX && errno==ERANGE)
{
//out of range!
break;
}
}
printf("\n\n%lu", sum_val);
So the value of sum_val for the string "12abcd4" would be 16.
scanf() is usually not the best way to accept input that is not well-formatted. Maybe you can use fgets()-sscanf() combo instead.
If you must use scanf(), make sure that you check the value returned by it, which in your case must be 1 (the number of successful assignments that scanf() made).
And to prevent overflow, use a width specifier as in
scanf("%99s",ch);
instead of
scanf("%s",ch);
as 100 is the size of the ch character array and we need one extra byte to store the string delimiter (the \0 character).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have to write a program that converts an user input (which is a string) to an Integer. In the same time it should check, if the user input really is a number.
And also everything in one method.
and NO LIBRARY FUNCTIONS allowed.
I can't figure any idea how to do it. All I got for the beginning is just this pathetic structure
#include <stdio.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%c, &input");
for (i = 0; i < 100; i++)
{
}
}
I appreciate any help, thanks
The conversion is the easy part...
But if you must not use library functions,
there is only one way to take a string, and that is argv;
there is only one way to give an integer, and that is the exit code of the program.
So, without much ado:
int main( int argc, char * argv[] )
{
int rc = 0;
if ( argc == 2 ) // one, and only one parameter given
{
unsigned i = 0;
// C guarantees that '0'-'9' have consecutive values
while ( argv[1][i] >= '0' && argv[1][i] <= '9' )
{
rc *= 10;
rc += argv[1][i] - '0';
++i;
}
}
return rc;
}
I did not implement checking for '+' or '-', and did not come up with a way to signal "input is not a number". I also just stop parsing at the first non-digit. All this could probably be improved upon, but this should give you an idea of how to work around the "no library functions" restriction.
(Since this sounds like a homework, you should have to write some code of your own. I already gave you three big spoons of helping regarding argv, the '0'-'9', and the conversion itself.)
Call as:
<program name> <value>
(E.g. ./myprogram 28)
Check return code with (for Linux shell):
echo $?
On Windows it's something about echo %ERRORLEVEL% or somesuch... perhaps a helpful Windows user will drop a comment about this.
Source for the "'0'-'9' consecutive" claim: ISO/IEC 9899:1999 5.2.1 Character sets, paragraph 3:
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
I'm sure this is preserved in C11, but I only have the older C99 paper available.
Take hightes digit and add it to number, multiply the number by 10 and add the next digit. And so on:
#include <stdio.h> // scanf, printf
void main()
{
char input[100];
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
int number = 0;
int neg = input[0] == '-';
int i = neg ? 1 : 0;
while ( input[i] >= '0' && input[i] <= '9' )
{
number *= 10; // multiply number by 10
number += input[i] - '0'; // convet ASCII '0'..'9' to digit 0..9 and add it to number
i ++; // step one digit forward
}
if ( neg )
number *= -1;
printf( "string %s -> number %d", input, number );
}
input[i] - '0' works, because ASCII characters '0'..'9' have ascending ASCII codes from 48 to 57.
So basically you want to know how something like the standard library atoi works. In order to do this, you need to consider how strings represent numbers.
Basically, a string (that represents a number) is a list o digits from 0 to 9. The string abcd (where a, b, c, d are placeholders for any digit) represents the number a*10 ^ 3 + b*10^2 + c * 10 + d (considering base 10 here, similar for other bases). So basically you need to decompose the string as shown above and perform the required arhitmetic operations:
// s - the string to convert
int result = 0;
for (int index = 0; index < strlen(s); index++) {
result = result * 10 + s[index] - '0';
}
The operation s[index] - '0' converts the character that represent a digit to its value.
// the function returns true for success , and false for failure
// the result is stored in result parameter
// nb: overflow not handled
int charToInt(char *buff,int *result){
*result=0;
char c;
while(c=*buff++){
if((c < '0') || (c >'9')) // accept only digits;
return 0;
*result *= 10;
*result += c-'0';
}
return 1;
}
Lot of things which are missed. Firstly taking a string in is done by scanf("%s",input); By the way in which you are receiving it, it only stores a character, secondly run the loop till the length of the string recieved. Check the below code.
#include <stdio.h>
#include<string.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
for (i = 0; i < strlen(input); i++)
{
if(input[i]>=48 && input[i]<=57)
{
//do something, it is a digit
printf("%d",input[i]-48);
//48 is ascii value of 0
}
}
Try it:
#include <stdio.h>
void main()
{
char input[100];
int i,j;
int val = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s",input);
for(j=0; input[j] != '\0'; j++); // find string size
for (i = 0; i < j; i++)
{
val = val * 10 + input[i] - 48;
}
}
If you want your code to be portable to systems that don't use ASCII, you'll have to loop over your char array and compare each individual character in the source against each possible number character, like so:
int digit;
switch(arr[i]) {
case '0':
digit=0; break;
case '1':
digit=1; break;
// etc
default:
// error handling
}
Then, add the digit to your result variable (after multiplying it by 10).
If you can assume ASCII, you can replace the whole switch statement by this:
if(isdigit(arr[i])) {
digit=arr[i] - '0';
} else {
// error handling
}
This works because in the ASCII table, all digits are found in a single range, in ascending order. By subtracting the ordinal value of the zero character, you get the value of that digit. By adding the isdigit() macro, you additionally ensure that only digit characters are converted in this manner.
I want to convert a char array[] like:
char myarray[4] = {'-','1','2','3'}; //where the - means it is negative
So it should be the integer: -1234
using standard libaries in C. I could not find any elegant way to do that.
I can append the '\0' for sure.
I personally don't like atoi function. I would suggest sscanf:
char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);
It's very standard, it's in the stdio.h library :)
And in my opinion, it allows you much more freedom than atoi, arbitrary formatting of your number-string, and probably also allows for non-number characters at the end.
EDIT
I just found this wonderful question here on the site that explains and compares 3 different ways to do it - atoi, sscanf and strtol. Also, there is a nice more-detailed insight into sscanf (actually, the whole family of *scanf functions).
EDIT2
Looks like it's not just me personally disliking the atoi function. Here's a link to an answer explaining that the atoi function is deprecated and should not be used in newer code.
Why not just use atoi? For example:
char myarray[4] = {'-','1','2','3'};
int i = atoi(myarray);
printf("%d\n", i);
Gives me, as expected:
-123
Update: why not - the character array is not null terminated. Doh!
It isn't that hard to deal with the character array itself without converting the array to a string. Especially in the case where the length of the character array is know or can be easily found. With the character array, the length must be determined in the same scope as the array definition, e.g.:
size_t len sizeof myarray/sizeof *myarray;
For strings you, of course, have strlen available.
With the length known, regardless of whether it is a character array or a string, you can convert the character values to a number with a short function similar to the following:
/* convert character array to integer */
int char2int (char *array, size_t n)
{
int number = 0;
int mult = 1;
n = (int)n < 0 ? -n : n; /* quick absolute value check */
/* for each character in array */
while (n--)
{
/* if not digit or '-', check if number > 0, break or continue */
if ((array[n] < '0' || array[n] > '9') && array[n] != '-') {
if (number)
break;
else
continue;
}
if (array[n] == '-') { /* if '-' if number, negate, break */
if (number) {
number = -number;
break;
}
}
else { /* convert digit to numeric value */
number += (array[n] - '0') * mult;
mult *= 10;
}
}
return number;
}
Above is simply the standard char to int conversion approach with a few additional conditionals included. To handle stray characters, in addition to the digits and '-', the only trick is making smart choices about when to start collecting digits and when to stop.
If you start collecting digits for conversion when you encounter the first digit, then the conversion ends when you encounter the first '-' or non-digit. This makes the conversion much more convenient when interested in indexes such as (e.g. file_0127.txt).
A short example of its use:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int char2int (char *array, size_t n);
int main (void) {
char myarray[4] = {'-','1','2','3'};
char *string = "some-goofy-string-with-123-inside";
char *fname = "file-0123.txt";
size_t mlen = sizeof myarray/sizeof *myarray;
size_t slen = strlen (string);
size_t flen = strlen (fname);
printf ("\n myarray[4] = {'-','1','2','3'};\n\n");
printf (" char2int (myarray, mlen): %d\n\n", char2int (myarray, mlen));
printf (" string = \"some-goofy-string-with-123-inside\";\n\n");
printf (" char2int (string, slen) : %d\n\n", char2int (string, slen));
printf (" fname = \"file-0123.txt\";\n\n");
printf (" char2int (fname, flen) : %d\n\n", char2int (fname, flen));
return 0;
}
Note: when faced with '-' delimited file indexes (or the like), it is up to you to negate the result. (e.g. file-0123.txt compared to file_0123.txt where the first would return -123 while the second 123).
Example Output
$ ./bin/atoic_array
myarray[4] = {'-','1','2','3'};
char2int (myarray, mlen): -123
string = "some-goofy-string-with-123-inside";
char2int (string, slen) : -123
fname = "file-0123.txt";
char2int (fname, flen) : -123
Note: there are always corner cases, etc. that can cause problems. This isn't intended to be 100% bulletproof in all character sets, etc., but instead work an overwhelming majority of the time and provide additional conversion flexibility without the initial parsing or conversion to string required by atoi or strtol, etc.
So, the idea is to convert character numbers (in single quotes, e.g. '8') to integer expression. For instance char c = '8'; int i = c - '0' //would yield integer 8; And sum up all the converted numbers by the principle that 908=9*100+0*10+8, which is done in a loop.
char t[5] = {'-', '9', '0', '8', '\0'}; //Should be terminated properly.
int s = 1;
int i = -1;
int res = 0;
if (c[0] == '-') {
s = -1;
i = 0;
}
while (c[++i] != '\0') { //iterate until the array end
res = res*10 + (c[i] - '0'); //generating the integer according to read parsed numbers.
}
res = res*s; //answer: -908
It's not what the question asks but I used #Rich Drummond 's answer for a char array read in from stdin which is null terminated.
char *buff;
size_t buff_size = 100;
int choice;
do{
buff = (char *)malloc(buff_size *sizeof(char));
getline(&buff, &buff_size, stdin);
choice = atoi(buff);
free(buff);
}while((choice<1)&&(choice>9));
I'm looking to read in a number from the keyboard and then I have to manipulate each digit individually (it's an Octal to Decimal converter).
Is there something similar to the charAt() method from Java that can be used to work with s particular digit?
I currently have the below code (incomplete) but when compiling, it returns "error: subscripted value is neither array nor pointer"
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
printf("Please enter an octal number ending with #");
char nextNum = getchar();
char number;
int counterUp = 0; //Records how many digits are entered
int counterDown = 1; //Records progress during conversion
int decimalNumber = 0;
while(nextNum != '#') //reads in the whole number, putting the characters together to form one Octal number.
{
number = (number + nextNum);
counterUp++;
nextNum = getchar();
}
//Begin converson from Octal to Decimal
while(counterUp >= 0)
{
int added = (number[counterUp] * (pow(8, counterDown)));
decimalNumber = (decimalNumber + added);
counterDown++;
}
}
I'm not looking to be told how to go from octal to decimal, just how to work with one digit at a time.
Use fgets() instead of a single char:
char number[25]; // max of 25 characters in string
fgets(number, 24, stdin); // read a line from 'stdin', with a max of 24 characters
number[24] = '\0'; // append the NUL character, so that we don't run into problems if we decide to print the string
Now you can subscript number at will, e.g. number[10] = 'A'.
I think you're used to Java way where you can write something like:
String number = "";
number += "3";
number += "4";
Strings in C do not work like that. This code doesn't do what you think it does:
char number = 0; // 'number' is just a one-byte number
number += '3'; // number now equals 51 (ASCII 3)
number += '4'; // number now equals 103 (meaningless)
Maybe something like this will work for you:
char number[20];
int i = 0;
number[i++] = '3';
number[i++] = '4';
Or, you could simply use scanf to read a number in from the keyboard.
I recommend that you find a good book about C and read about strings first, then scanf second.
I think you need to step back and look at your algorithm more closely.
What does char number store? What do you expect this loop to do:
while(nextNum != '#') //reads in the whole number, putting the characters together to form one Octal number.
{
number = (number + nextNum);
counterUp++;
nextNum = getchar();
}
In particular, what does number = (number + nextNum); mean?
You need to define number as an array of chars.
e.g.
char number[16];
Then change your reading loop to append to the array.
while(nextNum != '#')
{
number[counterUp] = nextNum;
counterUp++;
nextNum = getchar();
}