C - how to read input from text file to 2D array [duplicate] - c

Suppose,"5181 2710 9900 0012"- is a string of digits.I need to take one single digit at a time as input from the string of number without space to make arithmatic operations . So, i write that,
int a[20];
for(int i=0;i<16;i++)
{
scanf("%d",&a[i]);
}
but it didn't give me expected result. But when i use "%1d"instead of "%d",it gave me the expected result. so, how it works?

Since scanf is the inverse of printf, you could verify this by printing any number with the modifier (just a little tip).*
In general, the number before the format is a 'width' modifier. In this case it means you're only reading one byte into a number. If you specify %d, it may be a number of arbitrary length.
Example:
#include <stdio.h>
int main() {
int a;
sscanf("1234", "%d", &a);
printf("%d\n", a); // prints 1234
sscanf("1234", "%1d", &a);
printf("%d\n"m a); // prints 1
}
*) this appears to be false for this particular case. Makes sense that numbers are not truncated when specifiying a %d format, though, since that would change the meaning of the number. However, for many cases you could try what printf would do to predict scanf's behavior. But of course, reading the manual or docs on it is always the more helpful approach :)

Related

How to take one character at a time as input from a string of characters without space in c?

Suppose,"5181 2710 9900 0012"- is a string of digits.I need to take one single digit at a time as input from the string of number without space to make arithmatic operations . So, i write that,
int a[20];
for(int i=0;i<16;i++)
{
scanf("%d",&a[i]);
}
but it didn't give me expected result. But when i use "%1d"instead of "%d",it gave me the expected result. so, how it works?
Since scanf is the inverse of printf, you could verify this by printing any number with the modifier (just a little tip).*
In general, the number before the format is a 'width' modifier. In this case it means you're only reading one byte into a number. If you specify %d, it may be a number of arbitrary length.
Example:
#include <stdio.h>
int main() {
int a;
sscanf("1234", "%d", &a);
printf("%d\n", a); // prints 1234
sscanf("1234", "%1d", &a);
printf("%d\n"m a); // prints 1
}
*) this appears to be false for this particular case. Makes sense that numbers are not truncated when specifiying a %d format, though, since that would change the meaning of the number. However, for many cases you could try what printf would do to predict scanf's behavior. But of course, reading the manual or docs on it is always the more helpful approach :)

Adding two numbers in char variables read with scanf

I was teaching the C programming language to a friend and we came up with something I could not explain. This is the code we wrote:
#include <stdio.h>
int main(void)
{
char num1;
char num2;
printf("%s", "Enter the first number: ");
scanf("%d", &num1);
printf("%s%d\n", "The number entered is:", num1);
printf("%s", "Enter the second number: ");
scanf("%d", &num2);
printf("%s%d\n", "The number entered is:", num2);
printf("%s%d\n", "The first number entered was:", num1); /* This was done for testing */
printf("%s%d\n", "The sum is:", num1+num2);
return 0;
}
The weird thing is that we tried to do 5 + 6 and we expected to get 11 but instead got 6, I added a line to see what's going on with the first number and it becomes 0 after the second number is read.
I am aware that the variables should be an int (in fact the original code was like that and worked) but my understanding is that a char is a small integer so I thought it would be 'safe' to use if we were adding small numbers.
The code was tested and compiled on a Linux machine with cc and on a Windows machine with cl. The output was the same. On the Windows machine the program throw an error after the addition.
I would like an explanation on why this code is not working as I expected. Thanks beforehand.
You cannot pass a pointer to a different datatype to scanf. scanf will write to memory assuming you gave it a pointer to what it expected (e.g. int for %d), and will exhibit wonderful undefined behaviour if you give it a pointer to a different datatype.
Here, what is most likely happening is that scanf is overwriting e.g. 4 bytes on your stack when your chars only take up 1 byte, so scanf will just be happily writing right over some other variable on your stack.
a char is a small integer so I thought it would be 'safe' to use it if we were adding small numbers.
That is correct, char is a small integral type , and it's OK to use it in integer arithmetic(although char may be signed or unsigned which may causes the result unexpected).
But the problem is, a pointer to char can NOT be used in a place where a pointer to int is expected. And this is the case for scanf("%d", &num1);, the second parameter is expected to a of type int *.

Adding numbers until a negative is encountered

I'm trying to create a program that lets the user enter numbers(maximum entries>10^6) until a negative is encountered. I've tried a lot of version but they either don't register that a negative value is entered or they crash.
This is where I'm currently at:
#include <stdio.h>
#define HIGHEST 999999
int main(){
int i=0, entry, sum=0;
while(i<HIGHEST){
scanf("%i", entry);
if(entry>0){
sum+=entry;
}
else{
i=HIGHEST;
}
i++;
}
printf("Sum: %i", sum);
system("pause");
}
Your problem is on this line:
scanf("%i", entry);
Which should be:
scanf("%i", &entry);
You need to pass in the address of the integer variable that will store the scanned value. Since
entry was never initialized, it is just filled with garbage/whatever is in memory and not the entered value. See this reference, which states,
"Depending on the format string, the function may expect a sequence of additional arguments,
each containing a pointer to allocated storage where the interpretation of the extracted
characters is stored with the appropriate type"
You provide a way to leave if the entered number is too big:
while(i<HIGHEST){
But nothing to leave if it is less than 0; Try this:
while((i<HIGHEST)&&(i>=0)){
Additionally, #OldProgrammer is correct, your scanf() should be as he has pointed out.

segmentation fault in C programming

I started learning C programming and in this program I am trying to get user input and then a line at a time and decide if it contains non-int characters. I've been trying this method:
scanf("%d", &n);
if (isalpha(n))
{
i = -1;
}
I googled a bit and learned the function isalpha is good way to do it. However, I'm getting a segmentation fault every time I test the fragment above with non-int characters (letters for example). Any suggestion would be appreciated.
The %d format specifier forces scanf() to only accept strings of digits. Given anything else, it will fail and leave n unfilled (and assuming you didn't initialize n before, it will be filled with garbage).
The crux of the problem is that isalpha() expects a value between 0 and 255, and has an assertion to enforce it. At least on my VC++ compiler, it causes a crash with an access violation when given an invalid value (in non-debug mode).
To solve this you just have to switch to a %c format specifier. Converting n to a char would also be advisable as that makes your intent of reading a single character clearer.
EDIT: Given your clarifications in the comments, you can leave everything as is and simply check the return value of scanf() instead of going the isalpha() route. It returns the number of values read successfully, so when it encounters a non-integer or end of file, it will return 0. E.g.:
int main() {
int n;
while (scanf("%d", &n)) {
printf("Got int: %d\n", n);
}
}
I have no idea why you're getting a seg-fault. I'd have to see more of your program.
But using "%d" for scanf will only accept integer values and you'll get "0" for n that isn't an integer and therefore isalpha(n) will always be false and i will never be set to -1.
Perhaps you aren't initializing i and therefore it is never set. If you are referencing it later, that's probably the source of your seg-fault.
Use scanf("%c", &n), like this:
int main(char** argc, int argv) {
char n = 0;
int i = 0;
scanf("%c", &n);
if (isalpha(n)) {
i = -1;
}
printf("you typed %c, i=%d", n, i);
}
Make sure you have a character buffer to store the value in. Scan it as a string, and then use isalpha():
char buffer[32];
sscanf("%32s", buffer);
// loop and check characters...
if(isalpha(buffer[i])) ....
Note the use of %32s, this is to prevent buffer overflows (32 == size of buffer)
Given that n is an integer, we can diagnose that you are reading a value into n which is not in the range 0..255 plus EOF (normally -1), so that the code for isalpha(n) is doing something like:
(_magic_array[n]&WEIRD_BITMASK)
and the value of n is causing it to access memory out of control, hence the segmentation fault.
Since scanf():
Returns the number of successful conversions, and
Stops when there is a non-integer character (not a digit or white space or sign) in the input stream,
you can use:
#include <stdio.h>
int main(void)
{
char n = 0;
while (scanf("%c", &n) == 1)
printf("you typed %d\n", n);
return 0;
}

Is there a way to read a c-string and then an int with a single scanf in C?

Hey,
I'm trying to get this function to get the following output with the listed input, the "..." is where I'm not sure what to write:
void Question8(void)
{
char sentence[100];
int grade;
scanf(….);
printf("%s %d", sentence, grade);
}
Input:
My CS Grade is 1000
Output:
My CS Grade is 100
However, the kicker is that I need the scanf to read a c-string and then an int with a single scanf command, is this even possible?
Edit:
I can only edit the code in the location with the three periods ( "..." ), I cannot use anything more. I can assume that the input listed is expected but I cannot change anything outside of the three periods.
The output does not contain typos, the purpose of this assignment is to use flags and escape sequences.
It is possible to read pre-formatted string using scanf, however the format must be strict.
This version will continue to read the input until a digit is encountered and then read an integer.
Here is your code again:
char sentence[100];
int grade;
scanf("%[^0-9] %d",sentence,&grade);
printf("%s %d\n", sentence, grade);
I'll get this over with quick:
<obligatory_rant>
stupid question, but I guess it's homework and you're
stuck with these absurd limitations
</obligatory_rant>
Then, if you need to read everything up to but excluding the first digit, then the number:
if (scanf("%100[^0-9] %3d", text, &number) == 2)
...
Notes:
100 in "%100[... should be whatever your actual buffer size is to protect against buffer overrun.
The %3d documents that at most 3 digits should partake the the numeric value, so 1000 is correctly read as 100.
[^...] means the string made up of characters not ("^") in the following set, which is then specified as 0-9 - the digits.
if (... == 2) tests whether both positional parameters were scanned / converted successfully.
If you can't add an if and error message, then simply:
scanf("%100[^0-9] %3d", text, &number)
Tested in Visual Studio 2008
#include <stdio.h>
int main()
{
char sentence[100];
int grade = 0;
scanf("%[^0-9] %d",sentence,&grade);
printf("%s %d", sentence, grade);
return 1;
}
Input :
My CS Grade is 100
Output :
My CS Grade is 100
This is a really horrible question. A correct set of scanf parameters would be "%14c%3d", sentence, &grade
Because a space is included in the printf statement the trailing space needs to not be stored in sentence. Because the input contains other spaces there is no other solution (that I can thing of) than a fixed length. The integer parsing also requires a fixed length to truncate 1000 to 100.
I can think of no reason to ever write code anything like this. The code fits the requirements but wouldn't be useful in any other circumstances. I think that this is a very poor training exercise.

Resources