From a string "a ± bi" to number in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I need to convert a string in the a ± bi form to an int Real and an int Im. And in the case that the string isn't in that form, print an error. I have an idea to convert the a to the int and also the b but I don't know what to do with de imaginary number if it is positive.
i.e.
0,034 - 1,2i
>a=0,034
>b=-1,2
0,25
>Error, you must write in "a±bi" form
3,234 + 34,43i
>a=3,234
>b=34,43
ps: I found this link but it is in C++ and I don't know what it is doing
EDIT: THE REAL NUMBER COULD HAVE A PLUS OR MINUS.

It is quite simple, the C-standard has all you need:
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 100
// ALL CHECKS OMMITTED!
int main()
{
double a, b;
char buffer[BUFFER_SIZE];
int count = 0;
char c;
char *endptr;
while ((c = fgetc(stdin)) != EOF) {
if (c == '\n') {
// make a proper C-string out of it
buffer[count] = '\0';
// reset counter for the next number
count = 0;
// strtod() is intelligent enough to
// stop at the end of the number
a = strtod(buffer, &endptr);
// endptr points to the end of the number
// skip whitespace ("space" only)
while (*endptr == ' ') {
endptr++;
}
// skip the +/- in the middle
endptr++;
// strtod() skips leading space automatically
b = strtod(endptr, NULL);
printf("a = %g, b = %g\n", a, b);
}
// read all into a big buffer
buffer[count++] = (char) c;
if (count >= BUFFER_SIZE) {
fprintf(stderr, "Usage: type in complex numbers in the form \"a + b\"\n");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
See? No need to worry.

Use sscanf():
"%lf" scan 0 or more white spaces and then scan a double
" " scan 0 or more white spaces
"%1[+-]" scan a non-empty string made up of + or - and only up to 1 character in length.
"i" scan for an i character
"%n" store the count of characters scanned so far. (does not add to the return count.)
#include <complex.h>
#include <stdio.h>
double complex ALconvert(const char *s) {
int n = 0;
double re, im;
char sign[2];
if (sscanf(s, "%lf %1[+-] %lf i %n", &re, sign, &im, &n) != 3 || s[n]) {
puts("Error, you must write in \"a+/-bi\" form");
return 0.0/0.0; // TBD_ErrorCode;
}
if (sign[0] == '-') {
im = -im;
}
return re + im*_Complex_I;
}

Related

How to use strtol to extract numbers from user input

I'm trying to build a Linear Equation calculator in C. My source code is below. I know this is a coding question but to explain my issue, I need to explain a little math here. I have the user input the points in the format (x,y) and want to convert the equation into one of the following ways:
Slope-intercept -> y = mx + b
Standard form -> ax + by = c
Point-slope form -> y - y1 = m(x - x1)
y is the point on the y-axis of the coordinate plane, x is the point on the x-axis on the coordinate plane, m is the slope of a line, b is the y-intercept of the first equation, and a, b, and c are variables in the second equation.
My issue is that I'm having trouble finding a way to extract numbers from a coordinate. In my source code, I have a 2 dimensional array that holds 2 strings with a certain size. I don't know if i should use strtol() or something else. For example, take the point (34,89). I want to extract the 34 and 89 and plug it in to the values for finding the slope (which would be (y2 - y1) divided by (x2 - x1). So it would be (89 - y) / (34 - x). As for the second point, I want to be able to do the same thing. I would like to avoid making 4 variables for each point if possible. I would also like to avoid asking the user to enter the x value of the first point then the y value of the first point etc. etc. I want to be able to ask the user for a point, including both x and y values. Near the end of the code is unfinshed, so if i have errors, I'll figure them out as I go. The problem is near the beginning and middle.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define MAXC 56
//void convert_equation(); Function is not defined or used. Uncomment when ready to define
void equation_format();
void print_dots(int n);
char points[2][MAXC];
int main(void) {
printf("\033[0;32mInitializing Linear Equation Calculator ");
fflush(stdout);
print_dots (3);
putchar('\n');
printf("\nEnter the 1st point on the line, format (x,y)\n>>> ");
fflush(stdout);
fgets(points[0], sizeof points[0], stdin);
/** trim \n from end of string read with fgets()
*
* use: stringvar[strcspn (stringvar, "\n")] = 0;
*
* strcspn returns the length of stringvar that does NOT include \n
* this allows you to simply overwrite the \n with \0 (or plain old 0)
*/
points[0][strcspn(points[0], "\n")] = 0;
printf("Enter the 2nd point on the line, format (x,y)\n>>> ");
fflush(stdout);
fgets(points[1], sizeof points[1], stdin);
points[1][strcspn(points[1], "\n")] = 0;
equation_format();
return 0;
}
void equation_format() {
char option;
while (1) {
printf("\n\nWhat format would you like the equation in?\n1. Slope-Intercept\n2. Standard Form\n3. Point-slope\n>>> ");
fgets(&option, 2, stdin);
switch(option) {
case(1):{
int slope, yintercept;
break;
}
case(2):{
break;
}
case(3):{
break;
}
default: {
printf("Invalid input. Try again");
print_dots(3);
}
}
break;
}
}
void print_dots(int n) {
if (n < 0)
n = -n;
while (n--) {
sleep(1);
putchar('.');
fflush(stdout);
}
}
This is a little hard to explain so if I'm not being clear, please tell me. Thank you!
I want to be able to ask the user for a point, including both x and y values.
After fgets(), parse the string with a helper function, tailored to your needs.
Robust code also detects when the input is ill-formed.
// return 2 on success
// return -1 on failure.
int parse_2_int(const char *s, long *x, long *y) {
errno = 0;
char *endptr;
*x = strtol(s, &endptr, 0);
if (s == endptr || errno) return -1; // no conversion or overflow
s = endptr;
while (isspace((unsigned char) *s) { // skip spaces
s++;
}
if (*s != ',') return -1; // Missing ,
errno = 0;
*y = strtol(s, &endptr, 0);
if (s == endptr || errno) return -1;
s = endptr;
while (isspace((unsigned char) *s) { // skip spaces
s++;
}
if (*s != '\0') return -1; // junk at the end
return 2;
}
Usage
long x,y;
if (fgets(points[1], sizeof points[1], stdin)) {
if (parse_2_int(points[1], &x, &y) == 2) {
printf("Success %ld, %ld\n", x,y);
} else
printf("Trouble with <%s>\n", points[1]);
}
}
"My issue is that I'm having trouble finding a way to extract numbers from a coordinate.".
There are several way to convert a string to a number, strtol() and atoi() are either able to do this. Regarding user input, it is recommended that you keep the instructions to any user input as simple as possible. For example, rather than instructing a user to input "(34,89)", consider leaving the parenthesis off: "\nEnter the 1st point on the line, format: x,y\n>>> "
With that said, after user inputs are entered as say "56,78" and "3,7" and read into the string variables point1[0] and point1[1] respectively, it is a simple process to parse these into int (or long) members of a point struct using strtok():
typedef struct {
int x;
int y;
}POINT;
POINT p[2] = {0};
First, parse the string into char *, and convert:
char *tok = NULL;
tok = strtok(point[0], ",");
if(tok)
{
p[0].x = atoi(tok);
tok = strtok(NULL, ",");
if(tok)
{
p[0].y = atoi(tok);
)
And similar for p[1]. Then you can use the member pairs for x and y as arguments in the equation.
If strtol() is favored over atoi(), then adjust to replace:
p[0].x = atoi(tok);
with
p[0].x = strtol(tok, &ptr, 10);
As shown in the following:
typedef struct {
long x;
long y;
}POINT;
POINT p[2] = {0};
char *ptr = NULL;
p[0].x = strtol(tok, &ptr, 10);
//test return value for good results, and handle error if necessary
if(*ptr)
printf("Unable to convert '%s'.", tok);
else
...

Multiplying the numbers of a String [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I want to multiply the numbers in a given string which has one or more spaces.
Example:
If i input 52 26 23
the output should be 31096.
I've written this code but its not working:
#include <stdio.h>
int main()
{
char input[30];
int i, num = 0, v = 1;
gets(input);
for (i = 0; input[i] != '\0'; i++)
{
if(input[i] == 32)
{
v = v * num;
if(input[i+1] != 32)
{
num = 0;
continue;
}
}
num = (num * 10) + (input[i] - 48);
}
printf("%d",v);
return 0;
}
Try this one
#include <stdio.h>
#include <string.h>
int main()
{
char str[30];
char *token;
long int mul = 1;
gets(str);
token = strtok(str, " ");
while (token != NULL)
{
mul = mul * atoi(token);
token = strtok(NULL, " ");
}
printf("%ld",mul);
return 0;
}
The problem lies in your nested if statement. Once it enters the first if statement, that means input[i]==32, therefore it can never enter the next if statement where input[i]!=32.
I also have some suggestions for improving readability. Instead of using numbers to represent the characters, use the character literals themselves!
Another thing, you only have space for 30 characters in your input buffer. If a user attempts to enter more than this, you will have a buffer overflow.
Lastly, if the user puts more than one space between numbers, the output will become 0. That may be something you may or may not want to handle.
Edit: Before, the call to gets was only grabbing characters up to the first whitespace character. I've fixed this issue with a format string in a call to scanf instead. Buffer overflow problem still applies. Also, it was not multiplying with the last parsed integer, so I added code for that after the loop. Another note, this will only work for non-negative integers, if that's something you weren't aware of initially. The code just assumes the input is nice.
Edit 2: support for input with any number of spaces before, between, or after inputs.
#include <stdio.h>
int main() {
char input[30];
int i, num = 0, v = 1;
scanf("%[^\n]s", input);
// skip leading spaces
for(i = 0; input[i] == ' '; i++);
// parse remaining input
while(input[i] != '\0') {
if(input[i] == ' ') {
v *= num;
num = 0;
// skip subsequent spaces
while(input[++i] == ' ');
continue;
}
num *= 10;
num += input[i] - '0';
i++;
}
// ignore trailing spaces
if(input[i - 1] != ' ') {
// get last parsed integer
v *= num;
}
printf("%i\n", v);
return 0;
}

Trying to count the number of words in a file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a file named myf which has a lot of text in it and I am trying to use blank spaces as a way of counting the number of words. Basically, in the count method of my program, there is a variable int d which acts like a boolean function. Also, there is an incrementer called count.
I have a for loop which will traverse the array that's put into the argument of the method count, and will see if the pointer *p is a non letter. If it is a non letter AND d=0, d=1 and count is incremented. This way, if the next character is also a non space, since d=1, the else if statement will not be incremented again. The only way for d to reset to 0 is if a space is present, at which point, if another letter is found, it will be incremented again. Then the method count will return the variable count. Seems simple enough, but I keep getting wrong numbers.
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <ctype.h>
int count(char x[]) {
int d = 0;
int count = 0;
for (char *p = x; *p != EOF; *p++) {
// this will traverse file
printf("%c", *p);
// this is just to see the output of the file
if (*p == ' ' && d == 1) {
d = 0;
}
else if (*p != ' ' && d == 0) {
count++;
d = 1;
}
}
return count;
}
int main() {
char c;
int r = 0;
char l[1000];
FILE *fp = fopen("myf", "r");
while ((c = fgetc(fp)) != EOF) {
l[r] = c;
r++;
}
printf("\n %d", count(l));
}
To count the number of words, count the occurrences of a letter after a non-letter.
*p != EOF is the wrong test. EOF indicate that the input operation either 1) had not more input or 2) an input error occurred. It does not signify the end of a string.
Use int to save the result from fgetc() as that returns an int in the range of unsigned char and EOF. Typically 257 different values. char is insufficient.
Small stuff: No need for an array. Let code consider ' as a letter. As the number of words could be very large, let code use a wide type like unsigned long long.
#include <ctype.h>
int isletter(int ch) {
return isalpha(c) || c == '\'';
}
#include <stdio.h>
int main(void) {
unsigned long long count = 0;
FILE *fp = fopen("myf", "r");
if (fp) {
int c;
int previous = ' ';
while ((c = fgetc(fp)) != EOF) {
if (!isletter(previous) && isletter(ch)) count++;
previous = ch;
}
fclose(fp);
}
printf("%llu\n", count);
}
Don't do this
*p != EOF
EOF is actually a negative integer and you're using it as a char. You should pass in how many character you want to iterate over ie
int count(char x[], int max){
then use the for loop like
int m = 0;
for ( char *p = x; m < max; p++, m++)
Note I also changed *p++ to p++. You also need to update your program to consider things that are non space etc ie this line
else if (*p != ' ' && d==0 )
What happens when it encounters a \n, it will likely count an extra word.

C Getting decimal input from user issue

I'm trying to write a function to get a decimal input from the user and return the actual value converted from ASCII. However, the function causes the next input from the user to be skipped. As in:
Enter input: 123
Enter input: /* doesn; allow for input */
Enter input: 456
long sum = 0;
int character = fgetc(stdin);
while(character != '\n'){
if(character >= '0' && character <= '9'){
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
}
else{
/* reenter number */
}
character = fgetc(stdin);
}
return sum;
To figure out why your code doesn't work, I suggest you post your full code, because problems may lie in the way you call this function.
So before full code is posted, I can just tell you that this code works well on my machine:
#include <stdio.h>
#include <ctype.h>
int getlong();
int main() {
printf("\t%d\n", getlong());
printf("\t%d\n", getlong());
return 0;
}
int getlong() {
long sum = 0;
int character = fgetc(stdin);
while (character != '\n') {
if (isdigit(character)) {
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
character = fgetc(stdin);
}
else {
character = fgetc(stdin);
continue;
}
}
return sum;
}
ctype.h is included in order to use isdigit(), while tells you whether a character is decimal digit.
But in fact, you don't have to do everything on your own. Using standard library is more effective and efficient, both for you and for the computer.
For example, you can scan a long integer directly from stdin:
#include <stdio.h>
int main() {
long value;
puts("Please input numbers:");
while (scanf(" %ld", &value) != 1) {
puts("Only numbers are welcome:");
scanf("%*[^\n]");
}
printf("%ld", value);
return 0;
}
Notice the white-space at the beginning of format, this makes scanf() discard all white-space characters(including spaces, newline and tab characters) extracted until a non-white-space character is met.
Or, use strtol(), while is relatively rarely seen:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buf[80];
char *pEnd;
long value;
do
{
puts("Numbers please:");
if (fgets(buf, 80, stdin) == NULL)
{
perror("fgets()");
return 1;
}
value = strtol(buf, &pEnd, 10);
}
while (*pEnd != '\n');
printf("%ld", value);
return 0;
}
Of course, sscanf() also works, you can just write the code on your own.
From comments:
an extra newline in the stdin buffer...
Try replacing your current method with scanf() using following format string:
char* fmt = "%[^\n]%*c";
It reads everything up to the newline, then consumes the newline. * is an assignment suppressor.
Example: (includes functions to convert input string to float/integer number)
float get_float(void);
long get_int(void);
int main(void)
{
float num_f = get_float();
long num_i = get_int();
return 0;
}
float get_float(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter floating point number and hit return:\n");
scanf(fmt, input);
return strtod(input, dummy);
}
long get_int(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter integer number and hit return:\n");
scanf(fmt, input);
return strtol(input, dummy, 10);
}
Note: These functions are bare bones illustrations of how converting input into number variables might be done, and were written without any error or range checking. As the commenter has stated, it would be worth your while before implementing production versions to read up on strtol() and strtof in detail. (Links are to the Linux man pages, but because both functions are part of the C standard libraries, documentation can also be found on MSDN here and here)
Why not just use fgets and sscanf?
char buf[80];
float n;
if (fgets(buf, 80, stdin) != NULL) {
if (sscanf(buf, "%f", &n) == 1)
printf("%f\n", n);
else
fprintf(stderr, "invalid float\n");
}

Print every number with 0 in their digits (Only natural) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
The program requires a user to insert a number. Let's say we put 149. Now the program prints every number that has 0 digits in them till the number 149 (Including the number). So it's going to be 10,20,30,40,50,60,70,80,90,100,101...110..140 [Let's say the limit would be till 10000]
I have been trying to do this, but i only added +10 to every one, but that cannot be done >100 where it is 101,102..
Use the function sprintf to convert an integer to a string and then search for the character '0' in the string. If found, then print the number. Here's a simple working program implementing this idea.
#include <stdio.h>
#include <string.h>
#define MAXLEN 50 // max number of digits in the input number
int main(void) {
char buf[MAXLEN + 1]; // +1 for the null byte appended by sprintf
char ch = '0'; // char to be searched for in buf
int i, x;
if(scanf("%d", &x) != 1) {
printf("Error in reading input.\n");
return -1;
}
for(i = 1; i <= x; i++) {
sprintf(buf, "%d", i); // write i to the string buffer and append '\0'
if(strchr(buf, ch)) // strchr returns a pointer to ch if found else NULL
printf("%d\n", i);
}
return 0;
}
You can also extract each digit of an integer in the given range and check it for zero. Here's a naive implementation.
#include <stdio.h>
int main(void) {
int i, x;
int r;
if(scanf("%d", &x) != 1) {
printf("Error in reading input.\n");
return -1;
}
for(i = 1; i <= x; i++) {
for(r = i; r > 0; r /= 10) {
if(r%10 == 0) {
printf("%d\n", i);
break;
}
}
}
return 0;
}
The simple approach would be to iterate through all natural numbers up to the target number and testing each of them to see if they have any zero digits. Note that the last digit of a non-negative integer i can be obtained as the remainder from division by the base (i % 10 here). Also remember that integer division in C truncates decimals, e.g., (12 / 10) == 1
As a start, consider to convert each number to char [] and then check whether it contains a '0' or not.
To read on:
How to check if a int var contains a specific number
Count the number of Ks between 0 and N
I think this would be the answer.
int j;
for(int i=1;i<150;i++){
j=i;
while(j>0)
{
if(j%10==0)
{
printf("%d\n",i);
break;
}
else
j=j/10;
}
}

Resources