Odd behavior when converting strings to integers in C - c

Was working on a program taking a mathematical expression as a string and then evaluating it and discovered an odd behavior. Given
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
int ary[4];
char * string = "123+11";
for (int i = 0; i < 3; i++){
ary[i] = atoi(&string[i]);
printf("%d\n", ary[i]);
}
}
I get the output:
123
23
3
Whereas I might have expected I get the output:
1
2
3
Is this part of the atoi() function?

This is correct behavior because atoi takes a pointer to char as input and convert it into int till it finds "\0" character.
char * string = "123";
"\0" in string is present after 123.
For statement:
ary[0] = atoi(&string[0]);
atoi starts with 1 convert it to int till 123.
For statement:
ary[1] = atoi(&string[1]);
atoi starts with 2 convert it to int till 23.
For statement:
ary[2] = atoi(&string[2]);
atoi starts with 3 convert it to int till 3.
Please let me know if it is not clear.

The answer given by user3758647 is correct. To solve you problem you can use strtok function which tokenizes the input string based on delimiter.
char* string = "123+23+22";
char *token = strtok(string, "+");
int arr[4], i = 0;
arr[i] = atoi(token); //Collect first number here
while (token != NULL)
{
token = strtok(NULL, " ");
//You can collect rest of the numbers using atoi function from here
i++;
arr[i] = atoi(token);
//Do whatever you want to do with this number here.
}
return 0;

Related

C programming. Function to generate a string of random letters using only arrays and then pointers

Im trying to code a program in C to generate a string containing random letters using only arrays first and then again using pointers. I've looked at many other questions but is not quite what I'm trying to accomplish. I can really use help please.
Function 1- Generates a string with random upper
case letter A-Z with 40 characters.
Function 2- Function to let user enter a string
with random upper case letter and a replacement character.
Function 3- Searches string1 from function 1 and replaces
occurences of any character from string 2 (user entered) with
replacement character.
OUTPUT EX.
String 1- "AABBCCDDEEFFGGHHABCDEFGH"
String 2- "BE"
Replacement char- "3"
Filtered string- AA33CCDD33FFGGHHA3CD3FGH.
This is what I have so far, Im not very good with arrays.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int s1 [41];
srand(time(NULL));
int i;
for (i = 0; i < 41; i++)
{
s1 [i] = rand();
}
return 0;
}
Any help will be appreciated.
Thanks alot.
#include <stdio.h>
#include <stdlib.h>
void rand_str(char* txt, size_t sz)
{
int i=sz-1;
while( i --> 0 )
{
txt[i] = 'A' + rand() % 26;
}
printf("Random Str: %.*s\n", sz+i, txt);
}
void fn2(char* tgt, size_t sz, char* repl )
{
puts("String 2: ");
fgets(tgt, sz, stdin);
puts("Replacement Char: ");
*repl = getchar();
}
void search_replace(char* txt, char* tgt, char repl)
{
while(*tgt != '\0')
{
while ((strchr(txt, *tgt) ? (tgt[strchr(txt, *tgt)-tgt] = repl) : 0) == repl);
tgt++;
}
}
int main(void)
{
char txt[41] = {0};
char tgt[40] = {0};
char repl;
rand_str(txt, sizeof(txt));
fn2(tgt, sizeof(tgt), &repl);
search_replace(txt, tgt, repl);
return !printf("Filtered String: %s\n", txt);
}
Please note that I did not compile any of this code. It might have some typo and/or runtime errors. The concept is correct though and you should understand the code first and not just copy it.
Function 1:
#include <stdlib.h> // Important! rand() function that generate random function is in that library!
//This function returns a pointer of an array (arr). In other words it returns the **address** of the first character of the array.
// Assuming arr is valid!
char* randomString(char* arr){
// This part does not REALLLYY matters it just makes sure the random will truly be random...
time_t t;
srand((unsigned) time(&t)); // Seeds the random function.
//------------------
//Looping the array assigning random letters:
int i = 0;
while(i<SIZE){
arr[i] = 'A'+(rand()%('Z'-'A'+1));// 'A' has a numerical value, we want the range from 'A' to 'Z' to be random. 'Z'-'A' is the range of letters (26) because its a modulu if the modulu was just 'Z'-'A' (26) it wouldnt print Z. 'Z' is the 26th letter, 26%26 is zero, it will not give 'Z' this is why I increased 'Z'-'A' by 1 so the modulu will include 'Z' as random latter.
i = i + 1;
}
arr[i] = 0;// String terminator also called NULL.
return "lol";
}
Function 2:
#include <string.h>
int replace(char* inputString, char* userInput,char replacement ){
/* e.g.
inputString = "ABSDSADASBBBAA";//Generate yourself... (Might want to user function 1)
userInput = "AB"; // You need to do the user input yourself...
replacement = 'D';
*/
int i = 0;
while(i<strlen(inputString)){
int j = 0;
while(j<strlen(userInput)){
if(inputString[i]==userInput[j]){
inputString[i] = replacement;
}
j = j+1;
}
i = i + 1;
}
}
Function 3:
int main(){
// Just use regular IO libraries to get user's input...
// Assuming you did that, I will hard code the values (you need to do the IO e.g. gets())
char str[SIZE];
randomString(str); // Requirement #1 reuse of function 1
char * userInput = "AB"; // You need to do the user input yourself...
char replacement = 'D';// You need to do the user input yourself...
replace(str, userInput, replacement)//Requirement #2
return 0;
}

Beginner C, why is a bunch of random stuff added to my string?

I have the following program that I want to read in my name (Sahand) character by character and store in a string:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[6];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
The output is this:
s
Our temp is: s
Our total string is: s
a
Our temp is: a
Our total string is: sa
h
Our temp is: h
Our total string is: sah
a
Our temp is: a
Our total string is: saha
n
Our temp is: n
Our total string is: sahan
d
Our temp is: d
Our total string is: sahandd\350\367\277_\377
Program ended with the string: sahandd\350\367\277_\377
Program ended with exit code: 0
As you can see, everything is going fine until the final letter, d, is entered, when another d and a bunch of random stuff is added onto the string. Could someone explain to me what is happening here?
You should be adding the null character to the string before printing. Since you're printing inside a loop, add it to the next character. Just absolutely be sure that the for loop doesn't go beyond the bounds of the array.
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
Another option is to actually initialize each character in the C-String to be the '\0' character (without ever overwriting the last one); As some others have mentioned in the comments, this can be accomplished in the declaration of the array as such:
char str[7] = { 0 };
You need null character('\0') to end your string(array) at the 5th index in order to tell the compiler that this is the end of string(in your case character array i.e., str). But you were using 5th index to store character 'd'.
The compiler is taking garbage value from the memory
In order to run your program correctly, you need to declare the str array as below:
char str[7];
And insert null character('\0') at (i+1)th position.Look below:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
After reading the comments, I changed the following line in my program:
char str[6];
to
char str[7];
That did the trick and the program executes as I wish.
EDIT:
In addition to changing this line, I added a str[6] = 0; after the variable declaration.

how to use strtok to print a binary number?

So im trying to get a binary number from using the strtok function to iterate through a user inputted string. If the user inputs alpha it prints a 0 and if the user inputs beta it will output a 1.So if a user types in "alpha beta alpha beta alpha" the output should be "01010". I have the following code but im not sure where im going wrong as it is not doing the behavior i described
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main(int argc, char * argv[])
{
char userinput[250];
long binaryarray[250];
char *token;
int counter = 0;
long binarynumber = 0 ;
printf("enter alpha or beta");
scanf("%s", userinput);
token = strtok(userinput, " ");
while (token != NULL)
{
if(!strcmp(token, "alpha"))
{
binaryarray[counter] = 0;
counter += 1;
}
if(!strcmp(token, "beta"))
{
binaryarray[counter] = 1;
counter += 1;
}
token = strtok(NULL, " \0");
}
for(int i = 0; i < counter; i++)
{
binarynumber = 10 * binarynumber + binaryarray[i];
}
printf("%ld", binarynumber);
}
How would I fix this issue?
The problem is, for
scanf("%s",userinput);
the scanning stops after encountering the first whitespace. So, it cannot scan and store an input like
alpha beta alpha beta alpha
separated by whitespace. Quoting C11, chapter ยง7.21.6.2
s
Matches a sequence of non-white-space characters.
Possible Solution: You need to use fgets() to read the user input with whitespaces.
As already said by #SouravGhosh you should use fgets to store the whole string inserted by user with white spaces.
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[])
{
char userinput[250] = {0};
char binaryarray[250];
char* token;
size_t counter = 0;
printf("enter alpha or beta");
fgets(userinput, sizeof(userinput), stdin);
token = strtok(userinput, " \n\0");
while (( token != NULL) && (count < sizeof(binaryarray)))
{
if(!strcmp(token,"alpha"))
{
binaryarray[counter] = '0';
counter++;
}
else if(!strcmp(token,"beta"))
{
binaryarray[counter] = '1';
counter++;
}
token = strtok(NULL, " \n\0");
}
for(size_t i=0 ; i< counter; i++)
{
printf("%c", binaryarray[i]);
}
printf("\n");
}
But you have other problems:
Your tokens should be " \n\0" to match all possible chars between words.
All tokens must be checked with the first strok in case of a single input, so no whitespaces
Using an int to calculate your "binary" and print it with "%ld" format specifier does not print leading zeros. You can directly store chars into the buffer.

How to parse a string separated by commas? [duplicate]

This question already has answers here:
How do I parse out the fields in a comma separated string using sscanf while supporting empty fields?
(11 answers)
Closed 9 years ago.
Char *strings = "1,5,95,255"
I want to store each number into an int variable and then print it out.
For example the output becomes like this.
Value1 = 1
value2 = 5
Value3= 95
value4 = 255
And I want to do this inside a loop, so If I have more than 4 values in strings, I should be able to get the rest of the values.
I would like to see an example for this one. I know this is very basic to many of you, but I find it a little challenging.
Thank you
Modified from cplusplus strtok example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char str[] ="1,2,3,4,5";
char *pt;
pt = strtok (str,",");
while (pt != NULL) {
int a = atoi(pt);
printf("%d\n", a);
pt = strtok (NULL, ",");
}
return 0;
}
I don't know the functions mentioned in the comments above but to do what you want in the way you are asking I would try this or something similar.
char *strings = "1,5,95,255";
char number;
int i = 0;
int value = 1;
printf ("value%d = ", value);
value++;
while (strings[i] != NULL) {
number = string[i];
i++;
if (number == ',')
printf("\nvalue%d = ",value++);
else
printf("%s",&number);
}
If you don't have a modifiable string, I would use strchr. Search for the next , and then scan like that
#define MAX_LENGTH_OF_NUMBER 9
char *string = "1,5,95,255";
char *comma;
char *position;
// number has 9 digits plus \0
char number[MAX_LENGTH_OF_NUMBER + 1];
comma = strchr (string, ',');
position = string;
while (comma) {
int i = 0;
while (position < comma && i <= MAX_LENGTH_OF_NUMBER) {
number[i] = *position;
i++;
position++;
}
// Add a NULL to the end of the string
number[i] = '\0';
printf("Value is %d\n", atoi (number));
// Position is now the comma, skip it past
position++;
comma = strchr (position, ',');
}
// Now there's no more commas in the string so the final value is simply the rest of the string
printf("Value is %d\n", atoi (position)l

Convert char array to int array?

I'm beginner in C.
I have an char array in this format for example "12 23 45 9".
How to convert it in int array {12,23,45,9}?
Thanks in advance.
Use sscanf, or strtol in a loop.
The traditional but deprecated way to do this would be to use strtok(). The modern replacement is strsep(). Here's an example straight off the man page for strsep():
char **ap, *argv[10], *inputstring;
for (ap = argv; (*ap = strsep(&inputstring, " \t")) != NULL;)
if (**ap != '\0')
if (++ap >= &argv[10])
break;
That breaks inputstring up into pieces using the provided delimiters (space, tab) and iterates over the pieces. You should be able to modify the above to convert each piece into an int using atoi(). The main problem with strsep() is that it modifies the input string and is therefore not thread safe.
If you know that the input string will always contain the same number of ints, another approach would be to use sscanf() to read all the ints in one go:
char *input = "12 23 45 9";
int output[5];
sscanf(inputstring, "%d %d %d %d %d", &output[0], &output[1], &output[2], &output[3], &output[4]);
You can calculate the individual digits by using the following technique (but it won't convert them into the whole number):
Note I am using an int iteration loop to make it readable. Normally you'd just increment the char pointer itself:
void PrintInts(const char Arr[])
{
int Iter = 0;
while(Arr[Iter])
{
if( (Arr[Iter] >= '0') && (Arr[Iter]) <= '9')
{
printf("Arr[%d] is: %d",Iter, (Arr[Iter]-'0') );
}
}
return;
}
The above will convert the ASCII number back into an int number by deducting the lowest ASCII representation of the 0-9 set. So if, for example, '0' was represented by 40 (it's not), and '1' was represented by 41 (it's not), 41-40 = 1.
To get the results you want, you want to use strtok and atoi:
//Assumes Numbers has enough space allocated for this
int PrintInts(const int Numbers[] const char Arr[])
{
char *C_Ptr = strtok(Arr," ");
int Iter = 0;
while(C_Ptr != NULL)
{
Numbers[Iter] = atoi(C_Ptr);
Iter++;
C_Ptr = strtok(NULL," ");
}
return (Iter-1); //Returns how many numbers were input
}
You will need stdlib.h
//get n,maxDigits
char** p = malloc(sizeof(char*) * n);
int i;
for(i=0;i<n;i++)
p[i] = malloc(sizeof(char) * maxDigits);
//copy your {12,23,45,9} into the string array p, or do your own manipulation to compute string array p.
int* a = malloc(sizeof(int) * n);
int i;
for(i=0;i<n;i++)
a[i] = atoi(p[i]);
What about:
const char *string = "12 23 45 9";
int i, numbers[MAX_NUMBERS]; //or allocated dynamically
char *end, *str = string;
for(i=0; *str && i<MAX_NUMBERS; ++i)
{
numbers[i] = strtol(str, &end, 10);
str = end;
};
Though it maybe that you get a trailing 0 in your numbers array if the string has whitespace after the last number.

Resources