Trouble reading from file - c

So I think this should be pretty straight forward. I actually can't even understand what could possibly be going wrong, and that's what bugs me the most.
Here's the deal: I have to read a couple of numbers from a file, but these numbers are in scientific notation. An example file would have the numbers like this:
1.00090E+00,2.90000E+00
So I thought I'd simply read it like this: get a double, ignore a character, get an int, ignore a character, get another double, ignore a character, and get a final int, so for this example, it would:
get (1.00090)
ignore (E)
get (+00)
ignore (,)
get (2.90000)
ignore (E)
get (+00)
So, I wrote these fscanf:
fscanf(arquivo, " %lf%*c%d%*c", &mantissa1, &expoente1);
x[i] = numToFloat(mantissa1, expoente1);
fscanf(arquivo, "%lf%*c%d", &mantissa2, &expoente2);
fx[i] = numToFloat(mantissa2, expoente2);
I separated them to make the understanding simpler. But then, it doesn't work. It reads the first double correctly, but then it messes up the int. And then it messes up everything on the second fscanf.
I tried all that I could think of. Put the formatted string onto the fscanf ("%lfE%d," and "%lfE%d"). To read the signal into a character variable ("%lf%*c%c%d%*c"). None of it works.
Any guesses as to what's wrong?

First, you do not need to parse the mantissa and exponent separately. scanf natively understands n.nnnE±nnn notation. This is why your format string doesn't behave as you expect; the %lf directive consumes the entire first number including the E+00 piece, then %*c consumes the comma, %d the 2, and now we're hopelessly out of sync.
Second, you should not use any of thescanf functions, ever. Instead, read a line at a time with fgets (or getline, if you have it), split it on commas with strtok, and convert numbers to binary with strtod (which also natively understands scientific notation). This will be more coding up front, but the result will be easier to read and debug, it will be easier to make it robust against malformed input, and it will have well-defined behavior on input overflow.
(Technically you do not need to use strtok, as strtod will tell you where each number ends, but it is conceptually simpler to do the splitting first.)

You might be able to adapt this example to your needs, it used the %lg format specifier:
#include <stdio.h>
int main(void){
double d, e;
int n;
printf("Enter 2 scientific floats: ");
fflush(stdout);
n = scanf("%lg %*c %lg", &d, &e);
if(n == 2) {
printf("%f\n", d);
printf("%f\n", e);
} else {
printf("Bad input\n");
}
}
Program session
Enter 2 scientific floats: 1.8e+4,4.2e-1
18000.000000
0.420000

Related

how to take input int with % in c?

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.

How can I fix the scanf to take data into the array?

Can someone please advise regarding the scanf?
"message" is an array of 4 rows by 16 columns.
After the user enters the numbers (all 1 digit integers), when hitting "Enter" there is an error message. As said - probably something with the scanf.
for (int i = 0; i < M; i++) {
for (int j = 0; j < columns; j++) {
scanf("%d", message[i][j]);
}
}
[Answer adapted from a now-deleted former question.]
scanf seems like a nice, simple, easy, convenient way to read input. And in some ways it is, but it turns out that using it correctly can be surprisingly difficult, and it's chock-full of pitfalls.
You're probably not going to want to learn about all of scanf's intricacies at first. So for now, here are some guidelines for using a subset of scanf's functionality, safely. (For reasons I fail to understand, everybody tells beginners to use scanf, but nobody ever teaches rules like these along with it.)
Remember to always use & in front of the variables you're trying to read. (This is a special rule, for scanf only. Don't try to use that & on the variables you pass to printf, for example.)
Exception to rule 1: Do not use the & when you are reading strings with %s.
If you are reading strings using %s, make sure the variable you read into is either a character array that's big enough for what the user is likely to type, or a pointer to malloc'ed memory that's big enough for what the user is likely to type. (See also note below about avoiding overflow.)
Be aware that %s reads strings that don't contain space characters. You can't use %s to read strings (like full names) that might contain spaces. (For now, please don't worry about how you might read a string that might contain spaces. See also rule 14.)
Don't try to use scanf and fgets together in the same program.
Don't try to use scanf and getchar together in the same program.
Try to limit yourself to only the format specifiers %d, %s, %f, and %lf, to read into variables of type int, string (see rule 3), float, and double, respectively.
If you want to read a character into a variable of type char, you can use " %c", but the mysterious extra explicit space character there is vital.
Use only one % sign in the format string, to read one variable. Don't try to read two or more variables in one scanf call.
Always check scanf's return value. If it returns 0, or the negative value EOF, that means it didn't successfully read anything. If it returns 1, that means it successfully read one value. (And if you break rule 9, and try to read multiple values, it'll return the number of values it did successfully read, anywhere between 0 and the number you asked for.)
If scanf returns 0 or EOF, indicating that the user did not type a valid value, just print an error message and exit. Don't try to write code that asks the user to try again, because the user's wrong input is still sitting on the input stream, and there's no good, simple way to get rid of it. (If you really want to write user-friendly code that re-prompts in case of error, scanf is not the right tool for the job.)
Never put whitespace after the format string. That includes the newline character \n. (That is, use "%d", not "%d " or "%d\n".)
Don't try to use the %[…] specifier.
If you break rule 13 (perhaps because someone told you that %[…] might be a way to read a string containing spaces, or a whole line), do not put an s after it. The format is %[…], not %[…]s.
These rules may seem restrictive, but if you follow these rules, you should be able to simply and easily and reliably get simple inputs into your simple programs, which is the goal here. scanf is otherwise remarkably hard to use, and experience has shown that there are something like 17 different horribly frustrating problems that tend to come up, and trying to solve them is a completely unnecessary distraction from your goal of learning C by writing simple C programs.
When you're reading strings with %s or %[…], there's a danger: no matter how big the array or malloc'ed buffer you're reading into is, the user might type more than that. To avoid overflow, you can use a format like %19s to explicitly tell scanf how many characters it's allowed to read. (And remember to subtract 1, to leave room for the terminating '\0'. That is, you'd use %19s to read into char str[20]; or char *p = malloc(20);.)
These rules are somewhat numerous. For a simpler set of rules, see this answer. Putting rules 7, 8, 9, 12, and 13 together, there are really only five complete format strings you want to use with scanf: "%d", "%s", "%f", "%lf", or " %c". (But no commas, no fixed strings, no whitespace other than the explicit space in " %c", nothing else.) Exception: as mentioned above, it's fine to use something like %19s to limit the length of a string being read.
If you need to do something more complicated, that you can't do while staying within these rules, it's time to either:
Learn enough about how scanf really works (and doesn't work) so that you can try to do the thing you want, but without getting stuck on one of those 17 problems, or
Learn how to do input using better and more powerful methods than scanf, perhaps by reading whole lines using fgets and then parsing them.
You're missing a "&" before "message[i][j]".
for (int i = 0; i < M; i++) {
for (int j = 0; j < columns; j++) {
scanf("%d", &message[i][j]);
}
}

Store leading zeroes in C

For starters, I'm new to programming
I'd like to know how to store a number with leading zeroes in it with scanf instead of modifying the printf. Is it related to data types? If so, what is it? and how do I use it? I currently only know int, double and float
For example, I'd like to input the number "02" and receive "02" as the output, and when I input "2" the output will also be "2".
how to store a number with leading zeroes (?)
I currently only know int, double and float
To store an integer and the leading zero count is then 2 pieces of information. When reading user input, record the number and its length or textual width.
" " to consume whitespace.
"%n" to record the offset of characters scanned so far. This does not affect the return value of scanf().
int num;
int n1, n2;
if (scanf(" %n%d%n", &n1, &num, &n2) != 1) {
puts("Failed to read an int");
}
Otherwise, print it.
"0": pad with zeros.
"*": minimum width to print derived from argument list.
else {
int length = n2 - n1;
printf("%0*d\n", length, num);
}
Input/output
007
007
The result of using scanf specifiers d, i, o, u, x, a, e, f, g is a mathematical number. There are no leading zeros. Conceptually, there are no digits in a number; it is a pure mathematical entity. (As Jonathan Leffler notes, leading zeros in the input matter the i specifier; a leading zero changes the base to octal while interpreting the numeral. This is for input only; the result is still a number with no associated digits or base.)
To preserve the leading zeros of a numeral, you must treat it as a string. scanf can be used to read strings or individual characters with the s, c, and [ specifiers, although you might wish to use a simple get-character function such as getchar. You would have to count the leading zeros yourself. The remaining digits could also be handled as a string, or you could convert them to a number.
If you store the number as an integer (e.g., int) or floating point type, any formatting information is inevitably lost: only the binary representation of the number is stored. (It may help to consider it as saving the idea of the number, e.g., "two", not how it looks when written.)
You need to store any additional information elsewhere, such as by saving the original string and using that for output, or by saving the number of digits and applying that to the printf format. There are also decimal number libraries that can internally save the decimal representation of the number, but that is considerably heavier than using the native types.
(Alternatively, just settle on a canonical output format and use that regardless of input. Is the goal really to preserve any input formatting as is, or would it suffice to always add the leading zeroes to the output?)
As already explained, numbers don't have leading zeros.
You can however treat it as a string
printf("Enter num: ");
char buf[50];
scanf("%s", &buf);
printf("You entered: %s", buf);
If you've got an int value, internally it's always represented as a certain number of bits (or whatever your CPU uses to store numbers) so you have no control over this.
There's always "leading zeroes" in terms of the internal format, because, for example, because 2099 is actually 0b00000000000000000000100000110011 in 32-bit form. This gets more complicated due to endian issues, but the principle still holds.
The only time leading zeroes makes sense is if you're using binary coded decimal, which has fallen out of style, or string notation such as produced by sprintf type functions.
It's only humans that care about digits. As far as a computer's concerned it's equally difficult to add 1+1 as it is 6916863870493370158+6471945999301299985 because they're both 64-bit operations.

fscanf c programming wierd error

I am not new to programming, but I encountered this small problem and I can't seem to get it.
I want to read a file with dates and put them in another file with another format
Input example: 18.08.2015
Output example: 18-08-2015
Here is the code (dat1 has "r" permission and dat2 "w"):
char d[3];
char m[3];
char g[5];
while(fscanf(dat1,"%s.%s.%s\n",&d,&m,&g)==3)
{
fprintf(dat2,"%s-%s-%s\n",d,m,g);
}
On the other hand, this works fine if I use [space] instead of a [dot] in the input file.
(18 08 2015)
What am I missing? The solution has to be as simple as possible and with using fscanf, not fgetc or fgets, to be explained to students that are just beginning to learn C. Thanks.
The %s pattern matches a sequence of non-white-space characters, so the first %s will gobble up the entire string.
Why use char arrays at all, why not int?
int d;
int m;
int g;
while(fscanf(dat1,"%d.%d.%d\n",&d,&m,&g)==3)
{
fprintf(dat2,"%d-%d-%d\n",d,m,g);
}
The %d in fprintf will not output leading zeros though. You'll have to teach your students a little bit extra or leave it for extra credit.
Since the scanf format %s reads up to the next whitespace character, it cannot be used for a string ending with a .. Instead use a character class: %2[0-9] or %2[^.]. (Change the 2 to the maximum number of characters you can handle, and don't forget that the [ format code does not skip whitespace, so if you want to do that, put a space before the format code.)
Change
fscanf(dat1,"%s.%s.%s\n",&d,&m,&g)
to
fscanf(dat1,"%[^.].%[^.].%[^.]\n",d,m,g);

What is the use of the %n format specifier in C?

What is the use of the %n format specifier in C? Could anyone explain with an example?
Most of these answers explain what %n does (which is to print nothing and to write the number of characters printed thus far to an int variable), but so far no one has really given an example of what use it has. Here is one:
int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");
will print:
hello: Foo
Bar
with Foo and Bar aligned. (It's trivial to do that without using %n for this particular example, and in general one always could break up that first printf call:
int n = printf("%s: ", "hello");
printf("Foo\n");
printf("%*sBar\n", n, "");
Whether the slightly added convenience is worth using something esoteric like %n (and possibly introducing errors) is open to debate.)
Nothing printed. The argument must be a pointer to a signed int, where the number of characters written so far is stored.
#include <stdio.h>
int main()
{
int val;
printf("blah %n blah\n", &val);
printf("val = %d\n", val);
return 0;
}
The previous code prints:
blah blah
val = 5
I haven't really seen many practical real world uses of the %n specifier, but I remember that it was used in oldschool printf vulnerabilities with a format string attack quite a while back.
Something that went like this
void authorizeUser( char * username, char * password){
...code here setting authorized to false...
printf(username);
if ( authorized ) {
giveControl(username);
}
}
where a malicious user could take advantage of the username parameter getting passed into printf as the format string and use a combination of %d, %c or w/e to go through the call stack and then modify the variable authorized to a true value.
Yeah it's an esoteric use, but always useful to know when writing a daemon to avoid security holes? :D
From here we see that it stores the number of characters printed so far.
n The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by this call to one of the fprintf() functions. No argument is converted.
An example usage would be:
int n_chars = 0;
printf("Hello, World%n", &n_chars);
n_chars would then have a value of 12.
So far all the answers are about that %n does, but not why anyone would want it in the first place. I find it's somewhat useful with sprintf/snprintf, when you might need to later break up or modify the resulting string, since the value stored is an array index into the resulting string. This application is a lot more useful, however, with sscanf, especially since functions in the scanf family don't return the number of chars processed but the number of fields.
Another really hackish use is getting a pseudo-log10 for free at the same time while printing a number as part of another operation.
The argument associated with the %n will be treated as an int* and is filled with the number of total characters printed at that point in the printf.
The other day I found myself in a situation where %n would nicely solve my problem. Unlike my earlier answer, in this case, I cannot devise a good alternative.
I have a GUI control that displays some specified text. This control can display part of that text in bold (or in italics, or underlined, etc.), and I can specify which part by specifying starting and ending character indices.
In my case, I am generating the text to the control with snprintf, and I'd like one of the substitutions to be made bold. Finding the starting and ending indices to this substitution is non-trivial because:
The string contains multiple substitutions, and one of the substitutions is arbitrary, user-specified text. This means that doing a textual search for the substitution I care about is potentially ambiguous.
The format string might be localized, and it might use the $ POSIX extension for positional format specifiers. Therefore searching the original format string for the format specifiers themselves is non-trivial.
The localization aspect also means that I cannot easily break up the format string into multiple calls to snprintf.
Therefore the most straightforward way to find the indices around a particular substitution would be to do:
char buf[256];
int start;
int end;
snprintf(buf, sizeof buf,
"blah blah %s %f yada yada %n%s%n yakety yak",
someUserSpecifiedString,
someFloat,
&start, boldString, &end);
control->set_text(buf);
control->set_bold(start, end);
It doesn't print anything. It is used to figure out how many characters got printed before %n appeared in the format string, and output that to the provided int:
#include <stdio.h>
int main(int argc, char* argv[])
{
int resultOfNSpecifier = 0;
_set_printf_count_output(1); /* Required in visual studio */
printf("Some format string%n\n", &resultOfNSpecifier);
printf("Count of chars before the %%n: %d\n", resultOfNSpecifier);
return 0;
}
(Documentation for _set_printf_count_output)
It will store value of number of characters printed so far in that printf() function.
Example:
int a;
printf("Hello World %n \n", &a);
printf("Characters printed so far = %d",a);
The output of this program will be
Hello World
Characters printed so far = 12
Those who want to use %n Format Specifier may want to look at this:
Do Not Use the "%n" Format String Specifier
In C, use of the "%n" format specification in printf() and sprintf()
type functions can change memory values. Inappropriate
design/implementation of these formats can lead to a vulnerability
generated by changes in memory content. Many format vulnerabilities,
particularly those with specifiers other than "%n", lead to
traditional failures such as segmentation fault. The "%n" specifier
has generated more damaging vulnerabilities. The "%n" vulnerabilities
may have secondary impacts, since they can also be a significant
consumer of computing and networking resources because large
guantities of data may have to be transferred to generate the desired
pointer value for the exploit. Avoid using the "%n" format
specifier. Use other means to accomplish your purpose.
Source: link
In my opinion, %n in 1st argument of print function simply record the number of character it prints on the screen before it reach the the %n format code including white spaces and new line character.`
#include <stdio.h>
int main()
{
int i;
printf("%d %f\n%n", 100, 123.23, &i);
printf("%d'th characters printed on the screen before '%%n'", i);
}
output:
100 123.230000
15'th characters printed on the screen before '%n'(with new character).
We can assign the of i in an another way...
As we know the argument of print function:-
int printf(char *control-string, ...);
So, it returns the number the number of characters output. We can assign that return value to i.
#include <stdio.h>
int main()
{
int i;
i = printf("%d %f\n", 100, 123.23);
printf("%d'th characters printed on the screen.", i);
}
%n is C99, works not with VC++.

Resources