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
Related
I am trying to calculate the number of sentences inside any text on the basis that the end of each sentence may be !, ? or ., but when I used strcmp() it doesn't work as expected. so if the text contains ! and compared with character constant ! it doesn't give the correct output as 0 as assumed.
Although, I tried to test the outputs to understand what took place led to such result but I couldn't understand so can anyone help ?
Thank you.
here is my code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int count_sentences(string text);
int main(void)
{
string text = get_string("text: ");
//printf("%s\n", text);
count_sentences(text);
//printf("%i\n", strcmp("!", "!"));
}
int count_sentences(string text)
{
int string_length = strlen(text);
int num_of_sentences = 0;
const char sent_ind1 = '?';
const char sent_ind2 = '!';
const char sent_ind3 = '.';
//printf("%c %c %c", sent_ind1, sent_ind2,
//sent_ind3);
for (int i = 0; i < string_length; i++)
{
int value1 = strcmp(&text[i], &sent_ind1);
int value2 = strcmp(&text[i], &sent_ind2);
int value3 = strcmp(&text[i], &sent_ind3);
if (value1 == 0 || value2 == 0 || value3 == 0)
{
num_of_sentences += 1;
}
//printf("1- %i 2- %i 3- %i i- %c c- %c si0 %c si1 %c si2 %c\n",
//value1, value2, value3, i, text[i], sent_ind1, sent_ind2,
//sent_ind3);
//printf("1- %i 2- %i 3- %i i- %i\n",
//sent_ind1, sent_ind2, sent_ind3, text[i]);
}
//printf("string length equal %i and number of sentences equal %i.\n",
//string_length, num_of_sentences);
return num_of_sentences;
}
These records
int value1 = strcmp(&text[i], &sent_ind1);
int value2 = strcmp(&text[i], &sent_ind2);
int value3 = strcmp(&text[i], &sent_ind3);
does not make a sense. For starters the second arguments of the calls of strcmp do not point to strings.
Secondly even if they would point to strings the result of the calls will be equal to 0 only in one case when these characters '!', '?' and '.' are the last characters of the string text.
Instead of the function strcmp use functions strcspn and strspn.
For example the function can look the following way
#include <stdio.h>
#include <string.h>
size_t count_sentences( const char *text )
{
size_t n = 0;
const char *end_of_sentence = "!?.";
while ( ( text += strcspn( text, end_of_sentence ) ), *text != '\0' )
{
++n;
text += strspn( text, end_of_sentence );
}
return n;
}
int main( void )
{
const char *text = "Do you know C string functions? "
"Learn them!!! "
"They are useful.";
printf( "%zu\n", count_sentences( text ) );
}
The program output is
3
If you simply want to count a number of '!', '?' and '.' in the string you need to compare characters.
size_t count_sentences(string text)
{
size_t nos = 0;
size_t pos = 0;
while(text[pos])
{
if(text[pos] == '!' || text[pos] == '?' || text[pos] == '.') nos++;
pos++;
}
return nos;
}
strcmp compares the whole strings not looking for the substring in the string. In your case, you do not pass as a second parameter the string only the reference to single char (and it is not a valid string). It is an UB.
In addition to properly comparing a char with a char of a string answered elsewhere, consider a different way to count sentences.
How many sentences in these 2 strings?
No end punctuation
Screaming text!!! What???
To get 1 and 2 rather than 0 and 6. use ".?!" to enable an increment the next time a letter is seen.
size_t count_sentences1(const char *text) {
// Best to use unsigned char for is...()
const unsigned char *utext = (const unsigned char *) text;
size_t num_of_sentences = 0;
int start_of_sentence = 1;
while (*utext) {
if (isalpha(*utext)) {
num_of_sentences += start_of_sentence;
start_of_sentence = 0;
} else if (strchr(".?!", *utext)) {
start_of_sentence = 1;
}
utext++;
}
return num_of_sentences;
}
There are some 'clever' answers regarding "counting punctuation marks." Sadly, these would give an incorrect count when a sentence ends with an 'ellipse' ("...") or what some refer to as an "interobang" ("?!").
Without your CS50 library to test, I've a get_string() that returns a string complete with its trailing newline. This is 'optional' and needs to be adapted for your version of get_string().
// #include <cs50.h> // Don't have
#include <stdio.h>
#include <string.h>
int main() {
char *foo = get_string( "Enter several sentences: " );
foo[strlen(foo)-1] = '\0'; // Chop '\n' off if required
int count = 0;
while( strtok( foo, "?.!" ) )
count++, foo = NULL;
printf( "Number of sentences: %i.\n", count );
return 0;
}
Output:
Enter several sentences: Does. this! fulfill the? requirement????
Number of sentences: 4.
I have a string, like "101 1 13" and I need to split it to a int aux[3] --> resulting in aux[0] = 101, aux[1] = 1 and aux[2] = 13 (in this case). How can
I do that?
In the example of the code below I get op as a String and want to get the value of the INTs in there. Each int is divided in the string by a white space(" ").
Another detail: I need the code to compile with flag -std=c99, so the answer that was accepted would not work.
#include <stdio.h>
#include <stdlib.h>
//example of str = "101 1 14" (char *)
// example of output = {101, 1, 14}(int *)
int* stoi(char *str) {
// function to split str into 3 ints
}
int main() {
char op[10];
int num[3];
scanf("%s\n", op);
num = stoi(op);
printf("%d %d %d", num[0], num[1], num[2]);
return 0;
}
First you need to tokenize your input (break apart the input into distinct elements). Then you need to parse/integerize the individual tokens by converting them from strings to the desired format.
Sample Code
#include <stdio.h>
#include <string.h>
#define BUF_LEN (64)
int main(void)
{
char buf[BUF_LEN] = { 0 };
char* rest = buf;
char* token;
int i = 0;
int iArr[100] = { 0 };
if ( fgets(buf, BUF_LEN, stdin) != NULL )
{
strtok(buf, "\n"); // Remove newline from input buffer in case we want to call fgets() again.
while ( (token = strtok_r(rest, " ", &rest)) != NULL )
{
iArr[i] = strtol(token, NULL, 10);
printf("Token %d:[%d].\n", i, iArr[i]);
i++;
}
}
return 0;
}
Sample Run
1231 12312 312 1232 1312
Token 0:[1231].
Token 1:[12312].
Token 2:[312].
Token 3:[1232].
Token 4:[1312].
Try to replace your code by following code.
The new code works only if input contains only single space between integers.
Your code:
while(op[cont] != '\0') {
for(i = 0; op[cont] != ' '; i++, cont++) {
num[i] += op[cont];
}
printf("num[i] = %d\n", num[i]);
}
New code:
while(op[cont] != '\0')
{
if(op[cont] != ' ')
num[i] = num[i]*10 + (op[cont]- '0');
else
i++;
cont++;
}
See this example of how to do that:
char string [10] = "101 1 666"
int v [3], n=0, j=0;
int tam = strlen(string);
int current_Len = 0;
for(i=0; i<tam; i++){
//32 = ascii for White space
if(string[i] != 32){
n = n*10 + string[i] - '0';
current_len++;
} else if (current_len > 0){
v[j++] = n;
current_len = 0;
n=0;
}
}
if (current_len > 0){
v[j++] = n;
}
This answer is assuming you know how much integers your string contain at the time of writing your code. It also uses specific clang/gcc extension (typeof) and may not be portable. But it may be helpful to someone (I mainly wrote it because I had nothing good to do).
#include <stdio.h>
#include <string.h>
struct {int _[3];} strToInt3(const char (*pStr)[])
{
int result[3] = {0}, *pr = result;
for(register const char *p = *pStr; *p; ++p)
{
if(*p == ' ') ++pr;
else
*pr *= 10,
*pr += *p - '0';
}
return *(__typeof__(strToInt3(0)) *)result;
}
int main()
{
char op[10];
int num[3];
scanf("%10[^\n]", op),
//memcpy(num, strToInt3(op)._, sizeof(num));
//or
*(__typeof__(strToInt3(0)) *)num = strToInt3(op);
printf("%d %d %d", num[0], num[1], num[2]);
}
I've commented the copying of returned array using memcpy and added a structure assignment. Although both must be valid (not standard I guess but working in most cases) I prefer the second option (and maybe some compiler optimizers will).
Also I assume ASCII character set for chars.
I found an easier approach to the problem. I insert a scanf, that don't catch the space blanket and convert it using atoi. As it is just 3 ints it doesn't become so bad to use this simple, repetitive way of catching the values. And it work with the -std=c99 flag, that I needed to use.
scanf("%s[^ ]\n", op);
num[0] = atoi(op);
scanf("%s[^ ]\n", op);
num[1] = atoi(op);
scanf("%s[^ ]\n", op);
num[2] = atoi(op);
printf("%d\n", num[0]);
printf("%d\n", num[1]);
printf("%d\n", num[2]);
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;
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'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.