for a homework, we need to input simple formulas (such as 3*2, 4+10, 50/16, etc.) and calculate the result (and rest) using only addition, subtraction, and bit shifting. Anyway, I could use three subsequent input reading, however I thought I'd try getting the formula in one pass using fgets() and sscanf(). Here is what I have :
int *v; // value (left side)
int *m; // modifier (right side)
char *o; // operant
int res = sscanf(buffer,"%d%s%d",v,o,m);
But naturally, this does not work, because o gets all the remaining portion of the string, leaving m with nothing (m equals whatever value is where and when it is declared)
Now, what would be the proper way to accomplish this?
NOTE : I'm using a trim function to trim extra spaces.
Try %c instead of %s. If the operator is always a single character, and there are no spaces between the operator and the operands, this should work.
By the way, are you initializing v, m, and o to actually point to something? It would be much better to do this:
int v;
int m
char o;
int res = sscanf(buffer, "%d%c%d", &v, &o, &m);
As my "Intro to Programming in C" professor used to say: "C is dangerous. Practice safe C!".
You may use %[-+*/] (with your set of operators) to ensure, that operator string gets only operator characters.
Since you don't have extraneous spaces and operators are all one character long, you could use %c to fill in o.
Related
I have to take two inputs from the user with %
input example: 20% 30%
I tried this
scanf("%d%d ", &x,&y);
how can I input two values with %? I can only take two integer values.
%% matches literal % character, so this should do it:
int r = scanf("%d%%%d%%", &x,&y);
if(r != 2) {
puts("scanf error");
exit(1);
}
General note: it's more robust to read entire lines with fgets or POSIX getline, then parse them, for example with sscanf.
Also, please read scanf documentation on what %d and %% do, and what the return value actually means.
Firstly, are you really obligated to also take the %? Couldn't you instead ask the user to input integers?
If you still want to take inputs with %, I think you could treat your inputs as char*, iterate through them until you encounter the '%' char, and then delete it.
You could then use the atoi function to transform your char* into integers.
While reading from a file in C, I was told that I can add an * after the % to disregard that input. For example:
fscanf(inputfile, "%lf %lf %*lf", &num1, &num2);
In this example the pointer reads three double values, but only two of them need to be stored (the ones without the * sign after the % sign).
Could someone explain how it works, because as far as I know the * sign is used to initialize or step into a pointer?
The use of * is just a string constant chosen arbitrarily. It has no relation to pointer dereferencing. How it "works" is that the parser in scanf simply parses the type as it would normally then throws away the value rather than looking for a parameter to put it in.
I was trying to remove spaces of a string after scanning it. The program has compiled perfectly but it is not showing any output and the output screen just keeps getting shut down after scanning the string. Is there a logical error or is there some problem with my compiler(I am using a devc++ compiler btw).
Any kind of help would be appreciated
int main()
{
char str1[100];
scanf("%s",&str1);
int len = strlen(str1);
int m;
for (m=0;m<=len;){
if (&str1[m]==" "){
m++;
}
else {
printf("%c",&str1[m]);
}
m++;
}
return 0;
}
Edit : sorry for the error of m=1, I was just checking in my compiler whether that works or not and just happened to paste that code
Your code contains a lot of issues, and the behaviour you describe is very likely not because of a bug in the compiler :-)
Some of the issues:
Use scanf("%s",str1) instead of scanf("%s",&str1). Since str1 is defined as a character array, it automatically decays to a pointer to char as required.
Note that scanf("%s",str1) will never read in any white space because "%s" is defined as skipping leading white spaces and stops reading in when detecting the first white space.
In for (m=1;m<=len;) together with str1[m], note that an array in C uses zero-based indizes, i.e. str1[0]..str1[len-1], such that m <= len exceeds array bounds. Use for (m=0;m<len;) instead.
Expression &str1[m]==" " is correct from a type perspective, but semantically a nonsense. You are comparing the memory address of the mth character with the memory address of a string literal " ". Use str1[m]==' ' instead and note the single quotes denoting a character value rather than double quotes denoting a string literal.
Statement printf("%c",&str1[m]) passes the memory address of a character to printf rather than the expected character value itself. Use printf("%c",str1[m]) instead.
Hope I found everything. Correct these things, turn on compiler warnings, and try to get ahead. In case you face further troubles, don't hesitate to ask again.
Hope it helps a bit and good luck in experiencing C language :-)
There are many issues:
You cannot read a string with spaces using scanf("%s") , use fgets instead (see comments).
scanf("%s", &str1) is wrong anyway, it should be scanf("%s", str1);, str1 being already the address of of the string
for (m = 0; m <= len;) is wrong, it should be for (m = 0; m < len;), because otherwise the last character you will check is the NUL string terminator.
if (&str1[m]==" ") is wrong, you should write if (str1[m]==' '), " " does not denote a space character but a string literal, you need ' ' instead..
printf("%c", &str1[m]); is wrong, you want to print a char so you need str1[m] (without the &).
You should remove both m++ and put that into the for statement: for (m = 1; m < len; m++), that makes the code clearer.
And possibly a few more problems.
And BTW your attempt doesn't remove the spaces from the string, it merely displays the string skipping spaces.
There are a number of smaller errors here that are adding up.
First, check the bounds on your for loop. You're iterating from index 1 to index strlen(str1), inclusive. That's a reasonable thing to try, but remember that in C, string indices start from 0 and go up to strlen(str1), inclusive. How might you adjust the loop to handle this?
Second, take a look at this line:
if (&str1[m] == " ") {
Here, you're attempting to check whether the given character is a space character. However, this doesn't do what you think it does. The left-hand side of this expression, &str1[m], is the memory address of the mth character of the string str1. That should make you pause for a second, since if you want to compare the contents of memory at a given location, you shouldn't be looking at the address of that memory location. In fact, the true meaning of this line of code is "if the address of character m in the array is equal to the address of a string literal containing the empty string, then ...," which isn't what you want.
I suspect you may have started off by writing out this line first:
if (str1[m] == " ") {
This is closer to what you want, but still not quite right. Here, the left-hand side of the expression correctly says "the mth character of str1," and its type is char. The right-hand side, however, is a string literal. In C, there's a difference between a character (a single glyph) and a string (a sequence of characters), so this comparison isn't allowed. To fix this, change the line to read
if (str1[m] == ' ') {
Here, by using single quotes rather than double quotes, the right-hand side is treated as "the space character" rather than "a string containing a space." The types now match.
There are some other details about this code that need some cleanup. For instance, look at how you're printing out each character. Is that the right way to use printf with a character? Think about the if statement we discussed above and see if you can tinker with your code. Similarly, look at how you're reading a string. And there may be even more little issues here and there, but most of them are variations on these existing themes.
But I hope this helps get you in the right direction!
For loop should start from 0 and less than length (not less or equal)
String compare is wrong. Should be char compare to ' ' , no &
Finding apace should not do anything, non space outputs. You ++m twice.
& on %c output is address not value
From memory, scanf stops on whitespace anyway so needs fgets
int main()
{
char str1[100];
scanf("%s",str1);
int len = strlen(str1);
int m;
for (m=0;m<len;++m){
if (str1[m]!=' '){
printf("%c",str1[m]);
}
}
return 0;
}
There are few mistakes in your logic.
scanf terminates a string when it encounter any space or new line.
Read more about it here. So use fgets as said by others.
& in C represents address. Since array is implemented as pointers in C, its not advised to use & while getting string from stdin. But scanf can be used like scanf("%s",str1) or scanf("%s",&str[1])
While incrementing your index put m++ inside else condition.
Array indexing in C starts from 0 not 1.
So after these changes code will becames something like
int main()
{
char str1[100];
fgets(str1, sizeof str1 , stdin);
int len = strlen(str1);
int m=0;
while(m < len){
if (str1[m] == ' '){
m++;
}
else {
printf("%c",str1[m]);
m++;
}
}
return 0;
}
I was just wondering is there some way to read an array and then based upon the letters entered do something?
Like for example: if the roman numeral; MM was entered is there some way to see that 2 M's were entered and display the value for M?
output would be: 1000+1000.
Could you just tell me the name of the function, because it is for an assignment I dont want someone doing it for me, I just dont know where to start from.
example: char romanNumerals[2] = {"MMMCMXCVIII"};
char romanNumerals[2] = {"MMMCMXCVIII"};
Is not right as it can only hold 1 element(+1 for the \0). Change it to
char romanNumerals[] = "MMMCMXCVIII";
The compiler will choose the correct size for the array when doing the above initialization.
Then,you need a variable to add the sum of each roman number. So create
int sum=0;
And you need to loop the length of array times as you want to check each letter.
int i,len=strlen(romanNumerals);
for(i = 0;i < len;i++)
{
//body of for loop
}
string.h should be included in order to use strlen function which returns the length of a string.
Now,check each letter inside the body of the for loop using
if(romanNumerals[i]=='M')
sum=sum+1000;
else if(romanNumerals[i]=='C')
sum=sum+/*the corresponding value*/;
else if(...)
sum=sum+/*value*/;
//etc etc
And then at last,print sum.
Your best bet is to use the scanf function from stdio.h.
char str[3];
scanf("%s", str);
would store up to two characters from the standard input and the null terminator (\0) into the char array pointed at by str.
All other answers are correct, but keep in mind that if you just sum the input letters with a lookup (M=1000, C=100, X=10, V=5, I=1), having "MMMCMXCVIII" would mean 3000+100+1000+10+100+5+3 = 4218 and this is not what "MMMCMXCVIII" means in roman numerals (it actually means 3998 ).
For reasons explained in the link supplied by NSimon (see 1st comment) scanf() is not the best option when the input string length isn't known.
Other options are fgets() and getline(). The thing to remember is that a properly formed string is terminated by a null character - usually written '\0'. Hence if all else fails, you can always read char for char using the fgetc() function in a loop of some sort and stop when either your buffer is full or the '\0' is found.
So much for reading the array. When it comes to evaluating roman numerals, the best approach is to start at the back. Roman numerals have a (niot quite so simple) ordering:
I < V < X < L < C < D < M
Reading backwards you need to follow some straight forward rules:
The least significant packet is always last (i.e. IXL is wrong, it should be LIX = 59)
If X or V is preceeded by I then subract 1 otherwise add the value.
If L or C is preceeded by X then subtract 10 otherwise add the value.
If D or M is preceeded by C then subtract 100 otherwise add the value.
Note that M & D can only ever be preceeded by C or M. L & C can only be preceeded by X or C. X & V can only be preceeded by I or X. Anything else indicates a malformed number.
Thus working from the back it should be reasonably easy to obtain the correct value.
I have a string of the form
[S{i,j} : this is stack overflow]
I want to extract i,j and this is stack overflow in two separate strings.
sscanf will not work here as strings to be extracted can have spaces.
Can anyone please suggest an efficient way to do this?
If the string cannot contain the ending square bracket, you can absolutely use sscanf():
int i, j;
char text[128];
if( sscanf(input, "[S{%d,%d} : %127[^]]", &i, &j, text) == 3 )
{
printf("got it all!\n");
}
For more information about the somewhat lesser known conversion specifier [, see for instance this manual page. Basically, the conversion %[^]] means "all characters except a closing square bracket, it's a special form of the syntax using both negation (^) and doubling the closing bracket to include it in the set of negated characters.
UPDATE If you really mean "in two separate strings", then of course the above is wrong since it parses out the numbers into int-type variables. To get the pair as a string, use something like:
char ij[32], text[128];
if( sscanf(input, "[S{%31[^}]} : %127[^]]", ij, text) == 2 )
{
}