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.
Related
#include<stdio.h>
char bin(int);
int main()
{
setbuf(stdout,NULL);
int num;
char res[50];
printf("Enter the number: ");
scanf ("%d",&num);
res=bin(num);
printf("%s",res);
return 0;
}
char bin(int num)
{
char str[50];
int i,val;
for(i=0;num>=0;i++)
{
val=num%2;
str[i]=val;
num=num/2;
}
return str;
}
I really cant understand the error in the usage of strings... to convert the decimal to binary. Whats the conceptual error Im not following?
char is a single character, so char bin(int) will not be able to return a string (i.e. a null-terminated array of characters). And you cannot "return" an an array of characters, because C does not allow to return any array as function result. You can just pass/return pointers to the begin of such arrays.
So I'd suggest to change the interface of bin to reicieve the result buffer as parameter. Don't forget to "close" the string, i.e. to write the string termination character after the last "actual" character:
void bin(int num, char* resultBuffer) {
...
resultBuffer[i] = '\0';
}
In main, you call it then like
bin(num, res);
Returning str amounts to returning a local variable, you can't do it, what you can do is to return a pointer to a previously allocated memory block that works as an array (as an alternative to the oher answer, which is a good solution).
To do this you can declare str as a pointer, allocate memory for it and return it, making sure the variable to which the value is assigned is also a pointer, all the rest can remain the same.
There are, however, problems with the bin function.
Consider the statement:
str[i] = val;
This will not work as expected you are assigning the int result of the operation, which will be 1 or 0, you need to convert this value to the respective character.
The loop for (i = 0; num >= 0; i++) is an infinite loop because num will never be negative, unless you provide it a negative number in which case it will break in the first iteration, that is to say this code only works with positive integers. You need > instead of >=.
Finally you need to null terminate the string when the conversion is complete.
Corrected code (Online):
#include <stdio.h>
#include <stdlib.h>
char *bin(int); //return pointer
int main() {
setbuf(stdout, NULL);
int num;
char *res; //use pointer to receive string assignment
printf("Enter the number: ");
scanf("%d", &num);
res = bin(num);
printf("%s", res);
return 0;
}
char *bin(int num) {
char *str = malloc(50); // allocate memory
int i, val;
for (i = 0; num > 0; i++) { // replacing >= with >
val = num % 2;
str[i] = val + '0'; // convert to character
num = num / 2;
}
str[i] = '\0'; //null terminate the string
return str;
}
Note that you should also check for the inputed value, if it is larger than what an int variable can hold it will result in undefined behavior.
I'm trying to write a program which converts lower cased alphabet to numerical digits.
a -> 01
b -> 02
...
z -> 26
For the first nine letters I need to put a 0 before the number.
This is my code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXLEN 128
void s2n(char str[])
{
int i;
char x;
char result[256];
for (i=0; str[i] != '\0'; i++) {
x = str[i];
x = x - 96;
if (x < 10) {
char src[2] = {0, x};
strcat(result, src);
}
else {
char src2[1] = {x};
strcat(result, src2);
}
printf("%s", result);
}
}
int main(void)
{
char str[MAXLEN];
printf("Lower cased string please: ", MAXLEN);
scanf("%s", str);
s2n(str);
return 0;
}
Could you tell me what is wrong with my code??
One problem I see is:
char src[2] = {0, x};
You want to use the character 0, rather than the byte value 0 (NUL):
char src[2] = {'0', x};
Also, you need to NUL terminate your src array:
char src[] = {'0', x, 0};
The NUL termination would need to be done in both cases.
Another problem is your x = x - 96 statement also does not take into account that the character 0 is different from the byte value 0. So
x = x - 96 + '0';
would be better.
You use strcat() on an uninitialized array, result, it doesn't work that way, strcat() looks for the terminating nul byte in it's first parameter, and glues the second parameter from that point.
In your case there is no '\0' in result, calling strcat() with result as the first parameter causes undefined behavior.
You should at least ensure that there is one '\0' in result, you can do that by just setting the first element of result to '\0', like
result[0] = '\0';
Right before the loop starts, also you pass the second paramter src which is an array but is not a string, because it has no terminating '\0', but you actually don't need an array nor strcat().
You can use an index variable and just assing the ith element of the array to the actual character computed from the original value, like
result[i] = x;
Then you don't nul terminate result, which causes undefined behavior when you try to print resutl.
You also passing a parameter to printf() where it's not expecting one, that indicates that you are either silencing or ignoring compiler warnings.
There are many problems in your code, the following code, does what you want
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void s2n(char chr)
{
char result[4];
if (snprintf(result, sizeof(result), "%02d", 1 + chr - 'a') >= sizeof(result))
return;
printf("%s", result);
}
int main(void)
{
char chr;
printf("Lower cased string please: ");
if (scanf(" %c", &chr) != 1)
{
fprintf(stderr, "input error!\n");
return -1;
}
s2n(chr);
return 0;
}
note that no strings are required except the one where you are going to store the result, which you can build easily with sprintf().
I have written a C program. It's a character counting program. I will give input as below
Input: ABCAPPPRC
And need as output: A2B1C2P3R1.
But it gives output as A2B1C2A1P3P2P1R1C1. It basically doing as per the logic I have written in program. But I don't want to count the characters of string which have already been counted. Can you suggest what logic I should implement for this?
#include <stdio.h>
int main()
{
char str[30]= "ABCAPPPRC";
char strOutPut[60]="";
char *ptr= &str, *ptr2=&str;
char ch='A';
int count=0;
puts(str);
while (*ptr !=NULL)
{
count =0;
ch = *ptr;
while (*ptr2!= NULL)
{
if (*ptr2 == ch) count++;
ptr2++;
}
printf("%c%d",*ptr, count);
ptr++;
ptr2 = ptr;
}
}
You need to separate the counting from the printing.
The first loop goes through the input and counts the number of occurrences of each character, storing the counts in an array indexed by the character code.
The second loop goes through the array of counts and prints the character corresponding to a non-zero count followed by that count.
For example:
#include <stdio.h>
int main(void)
{
char str[] = "ABCAPPPRC";
int counts[256] = { 0 };
puts(str);
for (char *ptr = str; *ptr != '\0'; ptr++)
counts[(unsigned char)*ptr]++;
for (int i = 0; i < 256; i++)
{
if (counts[i] != 0)
printf("%c%d", i, counts[i]);
}
putchar('\n');
return(0);
}
Sample output:
ABCAPPPRC
A2B1C2P3R1
I could not understand the first for loop. Could you please explain it?
The for control line steps through the string str one character at a time. It is the for loop equivalent of the outer while loop in your original code.
char *ptr = str;
...
while (*ptr != '\0')
{
...
ptr++;
}
The body of the loop converts *ptr (a plain char) into an unsigned char (so that it is guaranteed to be positive), and then uses that value as an index into the array counts. Thus, for example, on the first iteration, A is mapped to 65, and counts[65] is incremented. Thus, for each character code, the loop increments the count corresponding to that character code each time the character is encountered in the string.
The second loop then picks out the non-zero counts, printing the character code as a character followed by its count.
(Incidentally, you should have been getting a compilation warning from the original char *ptr = &str about a type mismatch between char * and char (*)[30]. Learn when to put ampersands in front of array names — you seldom do it unless there is also a subscript after the array name. Thus, &array is usually — but not always — wrong; by contrast, &array[0] is very often valid. Also note that on some machines, NULL is defined as ((void *)0) and this elicits a warning when you compare it to a plain char, as you did with while (*ptr != NULL). You should compare characters to '\0' as in my rewrite; you should reserve NULL for use with pointers.)
str is alerady a character pointer, so when you do this: char *ptr= &str you convert a pointer to pointer to character to a char*. Loose the ampersand(&).
Also in the inner cycle you should check if the given value of ch has already been processed. In the case you use when ptr is pointing to the second A you should just continue, because you have already added the number of A-s in the answer.
Your solution is far from optimal. I strongly suggest you lookup counting sort. It will make your solution faster but also will make it simpler.
# Jonathan your solution is correct only when string characters are given in ascending order like ABCDEF, but it gives problem when character order is changed. Input string is "ABAPPPRCC" and required output is A2B1P3R1C2.
Here in this case your solution will change out put to A2B1C2P3R1.
Below program gives character count without changing string formation.
char *str= "ABAPPPRCC";
char strOutPut[30]="";
char *ptr = str, *ptr2 = str;
char ch='A';
int count=0, i = 0 , total_print = 0;
puts(str);
while (*ptr != '\0')
{
count =0;
ch = *ptr;
while (*ptr2!= '\0')
{
if (*ptr2 == ch) count++;
ptr2++;
}
for( i = 0; i < total_print ; i++ )
{
if ( ch == strOutPut[i] )
{
i = total_print + 1;
break;
}
}
if( i <= total_print )
{
printf("%c%d",*ptr, count);
strOutPut[total_print++] = ch;
}
ptr++;
ptr2 = ptr;
}
#include <stdio.h>
int main(void){
const char noncountchar = '\x11';
char str[30]= "ABCAPPPRC";
char strOutPut[60]="";
char *ptr, *ptr2;
char ch;
int count=0, len=0;
puts(str);
for(ptr=str;ch=*ptr;++ptr){
if(ch == noncountchar) continue;
count =1;
for(ptr2=ptr+1;*ptr2;++ptr2){
if (*ptr2 == ch){
*ptr2 = noncountchar;
++count;
}
}
len += sprintf(strOutPut+len, "%c%d", *ptr, count);
}
printf("%s", strOutPut);
return 0;
}
i need to get the ascii (int and hex format) representation of a string char by char. For example if i have the string "hello", i would get for int ascii 104 101 108 108 111
and for hex 68 65 6C 6C 6F
How about:
char *str = "hello";
while (*str) {
printf("%c %u %x\n", *str, *str, *str);
str++;
}
In C, A string is just a number of chars in neighbouring memory locations. Two things to do: (1) loop over the string, character by character. (2) Output each char.
The solution for (1) depends on the string's representation (0-terminated or with explicit length?). For 0-terminated strings, use
char *c = "a string";
for (char *i = c; *i; ++i) {
// do something with *i
}
Given an explicit length, use
for (int i = 0; i < length; ++i) {
// do something with c[i]
}
The solution for (2) obviously depends on what you are trying to achieve. To simply output the values, follow cnicutar's answer and use printf. To get a (0-terminated) string containing the representation,
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* convert a 0-terminated string to a 0-terminated string of its ascii values,
* seperated by spaces. The user is responsible to free() the result.
*/
char *to_ascii(const char *inputstring) {
// allocate the maximum needed to store the ascii represention:
char *output = malloc(sizeof(char) * (strlen(inputstring) * 4 + 1));
char *output_end = output;
if (!output) // allocation failed! omg!
exit(EXIT_FAILURE);
*output_end = '\0';
for (; *inputstring; ++inputstring) {
output_end += sprintf(output_end, "%u ", *inputstring);
//assert(output_end == '\0');
}
return output;
}
If you need to output an explicit-length string, use strlen() or the difference (size_t)(output_end-output).
int main()
{
enum type {decimal, hexa};
char *str = "hello";
char *temp_str = NULL;
temp_str = str;
static enum type index = decimal;
while (*str) {
if(index == decimal)
printf("%u\t", *str);
else
printf("%x\t",*str);
str++;
}
printf("\n");
if(index != hexa)
{
index = hexa;
str = temp_str;
main();
}
}
hope this will work fine as what u want, and if u want to store it in a uint8_t array, have to just declare an variable for it.
I know this is 5 years old but my first real program converted strings to ASCII and it was done in a clean and simple way by assigning a variable to getchar() and then calling it in printf() as an integer, all while it's in a loop of course, otherwise getchar() only accepts single characters.
#include <stdio.h>
int main()
{
int i = 0;
while((i = getchar()) != EOF)
printf("%d ", i);
return 0;
}
and here's the original version using the for() loop instead because I wanted to see just how small I could make the program.
#include <stdio.h>
int main()
{
for(int i = 0; (i = getchar()) != EOF; printf("%d ", i);
}
/* Receives a string and returns an unsigned integer
equivalent to its ASCII values summed up */
unsigned int str2int(unsigned char *str){
int str_len = strlen(str);
unsigned int str_int = 0;
int counter = 0;
while(counter <= str_len){
str_int+= str[counter];
printf("Acumulator:%d\n", str_int);
counter++;
}
return str_int;
}
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));