Converting a string of numbers into integers - c

I have a string (char) and I want to extract numbers out of it.
So I have string: 1 2 3 4 /0
And now I want some variables, so I can use them as integer: a=1, a=2, a=3, a=4
How can I do that?

The answers given so far are correct, as long as your string is formatted the way you expect. You should always check the return value of sscanf to make sure things worked okay. sscanf returns the number of conversions successfully performed, in the above case 4.
if (4 != sscanf(buf, "%d %d %d %d", &a, &b, &c, &d))
{
/* deal with error */
}
If buf was "1 2 3" or "1 2 a b" or something, sscanf would return a short item count.

As others have noted, if you know how many numbers to expect, sscanf is the easiest solution. Otherwise, the following sketches a more general solution:
First tokenize the string by spaces. The standard C method for this is strtok():
char* copy;
char* token;
copy = strdup(string); /* strtok modifies the string, so we need a copy */
token = strtok(copy, " ");
while(token!=NULL){
/* token now points to one number.
token = strtok(copy, " ");
}
Then convert the string to integers. atoi() will do that.

If the string always contains 4 numbers delimited with spaces, then it could be done with sscanf:
sscanf(string, "%d %d %d %d", &a, &b, &c, &d);
If the count of numbers varies, then you would need to parse the string.
Please clarify your question accordingly.

sscanf() can do that.
#include <stdio.h>
int main(void)
{
int a, b, c, d;
sscanf("1 2 3 4", "%d %d %d %d", &a, &b, &c, &d);
printf("%d,%d,%d,%d\n", a, b, c, d);
}

Related

Extract multiple integers from a string in C

I'm new to programming and I'm stuck at this basic problem: I have a string as input and it can contain things like 1,2c, 11,120p, 5u so basically 1 or 2 integers (if two, they are separated by ,) and a character at the end. I have to save the integers and the ending character in different variables, but I don't know how to do it and how to separate the case with 1 integer with the case with 2. Thanks for the answers.
You can use sscanf() to try and parse the string and check how many conversions succeeded:
#include <stdio.h>
void parse_string(const char *s) {
int n1, n2;
char c1, c2;
if (sscanf(s, "%d,%d%c%c", &n1, &n2, &c1, &c2) == 3) {
printf("2 numbers: %d and %d, character is %c\n", n1, n2, c1);
} else
if (sscanf(s, "%d%c%c", &n1, &c1, &c2) == 2) {
printf("1 number: %d, character is %c\n", n1, c1);
} else {
printf("invalid string format: %s\n", s);
}
}
In the above code, the string will be rejected if it does not match one of the formats, but also if there is a trailing character after the match, including a space. Note however that the match might not be strict enough as embedded spaces and a + or - sign in front of the numbers will also be accepted. The Standard C library does not include a more general pattern matching mechanism. An initial test such as if (sscanf(s, "%*[0-9],%*[0-9]%c%c", &c1, &c2) == 1) could be used to exclude spaces and signs but numbers exceeding the range of int would still pass this preliminary test and cause undefined behavior for the subsequent %d conversion.
You can use substring for this problem .
https://www.programmingsimplified.com/c/source-code/c-substring
int main()
{
char string[1000], sub[1000];
int position, length, c = 0;
printf("Input a string\n");
gets(string);
printf("Enter the position and length of substring\n");
scanf("%d%d", &position, &length);
while (c < length) {
sub[c] = string[position+c-1];
c++;
}
sub[c] = '\0';
printf("Required substring is \"%s\"\n", sub); // '\"' to print "
return 0;
}

How to read lines with different formats

I have an input file with the following form
i 176064 Patterson Denise 8.58 11 DEN 15788
q 188464
ra 148702 167443
a 73131
d 163464
f 6.00
ct 73131 PHY
b 3
p 15703
pe
m 144626 6.51 8
e
The first character in each line[i,q,ra,a...] represents an code to a function , while the rest are values that I must store into variables,depending on that code. What's the best way to achieve this ? I have been thinking about using fscanf but each line does not have a specific format, the format itself depends on the code [i,q,ra,a,b..]
To read a line, use fgets()
char buffer[100];
while (fgets, buffer, sizeof buffer, istream) != NULL) {
Then scan the line against the various formats, each ending with " %n". "%n" records the scan position, if it got that far. Additional tests could check for extraneous extras character starting at n.
int num1, num2, num3;
char last[sizeof buf];
char first[sizeof buf];
char code[sizeof buf];
double rate;
int n = 0;
// v..v..v..v...v..v..v spaces optional here
sscanf(buffer, "i %d %s %s %lf %d %s %d %n",
&num1, last, first, &rate, &num2, code, &num3, &n);
if (n) {
Handle_i();
continue;
}
sscanf(buffer, "q %d %n", &num1, &n);
if (n) {
Handle_q();
continue;
}
sscanf(buffer, "ra %d %n", &num1, &num2, &n);
if (n) {
Handle_ra();
continue;
}
sscanf(buffer, "e %n", &n);
if (n) {
Handle_e();
continue;
}
...
fail();
}
As each format begins with a unique letter pattern, the sscanf() will quickly exit on mis-match.
Alternative, code could parse out the initial letters for a slightly more efficient decision tree. Suspect profiling will show little performance difference.
As with any complex format, consider how one would maintain the code and it is bound to evolve.

How to read an unknown quantity of integers from console?

I have entries like these:
0 5 260
1 0 -598
1 5 1508
2 1 -1170
I don't know previously how many (console) inputs I'll get, so I have to read until there are no entries left.
I started with a code like this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)!=EOF){
// do stuff here
}
But it never stops asking for new input.
Then, I saw people in other threads suggesting this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)==1){
// do stuff here
}
In this case, it doesn't even enter the while.
Does anyone know what I'm doing wrong?
An approach: Continue asking for input until the input is closed (EOF) or some problem is encountered. (Invalid line of input)
The below uses fgets() to read a line.
Then, " %n" to detect where scanning stopped. If scanning does not reach %n, n will still have the value of 0. Otherwise it gets the offset in buffer where scanning stopped, hopefully it was at the null character '\0'.
char buffer[100];
while (fgets(buffer, sizeof buffer, stdin)) {
int n = 0;
sscanf(buffer, "%d%d%d %n", &a, &b, &c, &n);
if (n == 0) {
fprintf(stderr, "3 int were not entered\n");
break;
}
if (buffer[n] != 0) {
fprintf(stderr, "Extra input detected.\n");
break;
}
// do stuff here with a,b,c
}
There are many approaches to solve this issue.
while(scanf("%d %d %d", &a, &b, &c)==1)
means that "if scanf() successfully read just one value, proceed in the loop."
Therefore, if you enter something like 0 junk, the scanf() read just 1 data and will enter the loop once.
Try using
while(scanf("%d %d %d", &a, &b, &c)==3)
to have it enter the loop when scanf() successfully read three values, which is what expected.

How to use scanf in for loop

Whenever i try to read input with
for (int i = 1; i <= 10; ++i) {
scanf("(%c, %d, %d, %d)",&charv,&intv1,&intv2,&intv3);
}
I only get to scanf() once. What is the problem ?
Input -> (P, 1, 2, 3)......(P, 2, 3, 12)
Your usage of scanf() is wrong. You have to provide the pointer to the variable to store the value read by scanf(). You need to use it like below
for (int i = 1; i <= 10; ++i) {
scanf("%c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
}
EDIT:
Point 1: The supplied format string should exactly match with the input. Otherwise, scanf() will fail. If your input is not of format (<char>, <int>.... , it will fail. Either of missing (, ), , will cause mismatch in the supplied format string with the input and make scanf() to stop scanning. It's strongly recommended to check the return value of scanf() to ensure it's success.
Point 2: To avoid reading the \n stored by previous ENTER<\kbd> key press, you should add a leading space before %c. So, you can use something like
scanf(" %c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
^
|
Notice here
scanf("(%c, %d, %d, %d)",&charvar,&intvar1,&intvar2,&intvar3);
should be
scanf(" %c, %d, %d, %d",&charvar,&intvar1,&intvar2,&intvar3);
Note the space before %c which ignores newline if it exists. If your input is not separated by commas
scanf(" %c %d %d %d",&charvar,&intvar1,&intvar2,&intvar3);
Like Sourav Ghosh and Gopi said, scanf will not work properly with this syntax
scanf("(%c, %d, %d, %d)",&char,&int,&int,&int);
It should be
scanf("%c %d %d %d",&char,&int,&int,&int);
But you can read a string first, and then use sscanf.
Try this code:
char ch;
int a, b, c, i;
char teste[256];
for(i=0;i<10;i++){
fgets(teste, 256, stdin);
sscanf(teste, "(%c, %d, %d, %d)", &ch, &a, &b, &c);
printf("%c %d %d %d\n", ch, a, b, c);
}

convert int and char into a string

I have int x and char c. I want to make a new string called str as "x c"; so the int, a space, and the char.
So for example:
x = 5, c = 'k'
//concatenate int and char with a space in between.
so the line printf("%s", str) will print:
5 k
How do I do this in C code?
Use sprintf or snprintf to avoid safety of your code to be built on assumption that your buffer will be always big enough:
char str[100];
sprintf(str, 100, "%d %c", x, c);
But in case the only purpose of str will be to be used it to with printf, then just printf directly:
printf("%d %c", x, c);
...just don't use itoa since "this function is not defined in ANSI-C and is not part of C++"
These questions might help you as well:
How to convert an int to string in C
Converting int to string in c
char tmp[32]={0x0};
sprintf(tmp, "%d %c", x, c);
printf("%s\n", tmp);
or
printf("%d %c\n", x, c);
sprintf() can do what you want:
sprintf(str, "%d %c", x, c);
Since you want to print the information out, there is no reason (that I can see) to convert the data into a string first. Just print it out:
printf("%d %c", x, c);

Resources