I am new to programming in C and still trying to learn all of the useful functions it provides in its libraries. In particular I'm trying to wrap my head around how to use getchar() for more than one character in a certain situation. I want to be able to have input from the console be something like:
11 2 34 100
I want to be able to distinguish between these entries(delimiter space I guess?), and add these numbers up. This is an assignment, so I was wondering if someone could give me a hint or point me in the right direction on how to go further with this. I would certainly appreciate it. This is what I have at the moment. Also, we're not supposed to make use of arrays here. This really threw me because I don't see any other way. Again any help or pointers in the right direction would go a long way!
int main()
{
int count = 0;
char input;
int wordCount = 0;
int numEntered = 0;
input = getchar();
while(input != '\n')
{
if(input != ' ')
{
count++;
}
input = getchar();
}
printf("Number of characters included in numbers %d\n", count);
return 0;
}
You can store two integers, one that is the running total, and one that is the current number.
If you encounter a digit that is not a space, multiply the current number by 10 and then add that digit to the current number.
If you encounter a space, add the current number to the running total, then reset the current number to 0.
Related
I am taking in 10 numbers from the user (user enters them at a prompt, and the numbers are separated by commas, as so: 245645, -243, 4245). How can I put these elements into an array? As shown below, I have used scanf which does not work as I had hoped. Any suggestions would be appreciated.
//User will pass ten numbers, separated by commas. This is to be put into an array.
#include <stdio.h>
int main ()
{
int A[10]; // array to contain in users input.
printf("Enter your numbers: ");
scanf("%d", &A[10]);
return 0;
}
You have to consume the comma as well in scanf:
for(int i=0; i<10; i++) { /* for each element in A */
if(0==scanf("%d,", &A[i])) { /* read a number from stdin into A[i] and then consume a commma (if any) */
break; /* if no digit was read, user entered less than 10 numbers separated by commas */
/* alternatively error handling if fewer than 10 is illegal */
}
}
I won't write the whole thing for you.
But I can definitely help.
One of the ways to do that will be:
Get a string that contains 10 comma-separated numbers: fgets() may be?
Validate the string, trim white-spaces as well, makes life easier
Pick out a number from string: strtol() may be?
Search for a ',' character in the string, and set pointer to the next index after ',': strchr() may be?
Repeat steps 3 and 4 for a total of 10 times (from here, 9 times actually)
Print the numbers
The code below would do half of your job. The only remaining part would be to get string from user and validate it.
The intention to have a string declared and initialised upfront is to put more emphasise on actual parsing of data which appear complicated to beginners (no offence).
Before we look at the code below, lets read a few things first.
You might want to take a look at the man page for strtol() function
You might want to take a look at the man page for fgets() function, which is not used in the code below, but you may end-up using it to achieve step 1.
I already concede the fact that this may not be the best way to achieve it, and I would happily agree that this code below can be made better in thousand ways by adding various error check, but I leave that to you to explore and implement.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int i = 0, j = 0;
char *Str = "1,11,21,1211,111221,312211,1234,4321,123,789";
char *ptr;
long ret;
long array[10] = { [0 ... 9] = 0 };
// So, lets assume step 1 and 2 are taken care of.
// Iterate though the data for 10 times
for(i = 0; i < 10; i++)
{
ret = strtol(Str, &ptr, 10);
// Check if its a number
if(ret != 0)
{
// Its is a number!
// Put it in the array
array[j] = ret;
// Increment the index so that next number will not over-write the existing one
j++;
// Find the next ',' in the string
Str = strchr(Str, ',');
if(Str == NULL)
{
// Handle this condition that there are no more commas in the string!
break;
}
// Assuming that the ',' is found, increment the pointer to index next to ','
Str++;
}
}
// Print the array
for(i = 0; i < j; i++)
printf("%ld\n", array[i]);
}
This prints the following output:
1
11
21
1211
111221
312211
1234
4321
123
789
Hope I have got you started, Good luck.
I'd like some assistance with understand how inputting data in a program of C works. So far I'm used the java syntax having the convenient try{}catch(){}; clause but I don't see it anywhere on C (or I haven't found it?).
Assuming I have the following array;
float f_array[10];
Normally for me to input data I'd either use a scanf(...); or a file which I can read input from, but for the shake of simplicity let's assume I use scanf(...);
And I have the following;
int i;
for(i = 0; i<10; i++){
scanf("%f", &f_array[i]);
}
Now , my question is how to restrain the user from putting in the input a character or a string or the wrong data type for that matter? Also , should I always try to initialize the array before actually putting values in it?
Note that scanf() returns number of elements successfully read, you can check it:
int success = scanf(...);
if (!success) {
scanf("%*[^\n]%*c"):
// OR while(getchar() != '\n');
}
There is, however, a complex solution. You don't use scanf(), but write a custom input method that processes keystrokes and filters out invalid characters, possibly using getch() (Windows/nCurses). Here's a minimized Windows version:
void readFloat(float* in){
int ch, ind = 0;
char buf[100];
while (1){
ch = getch();
if (ch >= '0' && ch <= '9' || ch == '.') {
buf[ind++] = (char)ch;
putchar(ch);
}
else if (ch == 8) /* Backspace */ {
printf("\b \b");
ind --;
}
}
buf[ind] = '\0';
float ret;
sscanf(buf, "%f", &ret);
return ret;
}
So a possible result of the code:
User input (key presses): 123aaa.bbb456
Program filter (displayed on screen): 123.456
Return value: (float)123.456
Now , my question is how to restrain the user from putting in the input a character or a string or the wrong data type for that matter?
Without dedicated hardware support (say, using a keyboard that does not have letter keys, or some device that gives the user an electric shock to discourage them from hitting the 'A' key) there is no way to restrain a user from entering unwanted data.
Instead, you need to write your code with the ASSUMPTION that the user will enter invalid or poorly formed data, and cope with that. It is true that your code is simpler if you can assume an obedient and tractable user who only gives correct input, but the real world isn't like that.
scanf() - reading and interpreting data directly from stdin doesn't actually work well with such an assumption. The return value from scanf() can give you an indication a problem after the fact (e.g. the return value is number of fields successfully input, or EOF). However, when a problem occurs, scanf() handles it in a way you cannot control. Let's say you code has a
scanf("%f", &f_array[i]);
and the user hits the 'X' followed by the Enter key. scanf() will recognise the 'X' character is waiting to be read, and return immediately. The value it returns will not be 1 (which would indicate success). Even worse, the 'X' will be left to be read by a subsequent call of scanf() and the same will happen again (unless a different format is specified). Which means, if you call scanf() in a loop this way, the same will happen over and over again.
Some folks will tell you to simply find a way to read and discard the character 'X'. The problem with that approach is that there are MANY ways for the user to enter bad inputs, and you need to account for all of them. If the user does something you (or your code) doesn't expect, you get problems (e.g. program hanging waiting for the same input repeatedly, input being used as data when it isn't). You're back where you started.
The more robust approach is to simply read a line of input, and do checks before trying to extract a floating point value from it, such as
char buffer[20];
int got_one = 0;
while (!gotone && fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (check_string(buffer))
{
if (sscanf(buffer, "%f", &f_array[i]) == 1)
{
/* yay - we got a floating point value */
got_one = 1;
}
else
{
fprintf(stderr, "Floating point scanning failed. Try again\n");
}
}
else
{
fprintf(stderr, "Bad data discarded. Try again\n");
}
}
Essentially, this provides several hooks so you can check user input in various ways. If you want to, it can be adapted to discard part of a line, and scan useful data from whatever's left.
The key, however, is that the code does not assume the user is well behaved. It only attempts to read a floating point value after a gauntlet of checks, and still copes if the reading fails.
The code can also be adapted to deal with users who enter data that overflows the buffer (e.g. entering 30 floating point characters on a single line). I'll leave that as an exercise.
Also , should I always try to initialize the array before actually putting values in it?
That depends on the needs of your code, but generally speaking I would not bother.
With approaches like I suggest above, you can avoid a circumstance of using the array (or elements of the array) unless valid data has actually been put into it.
All initialising the array will do is obscure cases where the code doing input (reading from the user) has not properly dealt with bad user input.
give the user some feedback on a per input basis.
process each input and allow user to make corrections as you go.
use "atof()" to do the conversion, but it has a couple of quirks:
it tells you there is an error by returning a value of 0.0
it stops processing if/when it finds an invalid char and returns what it has up to that point
eg. 6.35k gives 6.35 -- this usually works out ok;
otherwise you have to check for invalid chars yourself.
try this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
float f_array[10];
int i;
float input_value;
char temp_string[32];
for(i = 0; i<10; i++){
printf("input a floating point number: ");
scanf("%s",&temp_string[0]);
input_value = atof(temp_string);
while(input_value == 0.0) {
printf("%s is not a valid floating point number\n");
printf("example is 5.6 or 1e32 or 17\n");
printf("try again - input a floating point number: ");
scanf("%s",&temp_string[0]);
input_value = atof(temp_string);
}
f_array[i] = input_value;
printf("String value = %s, Float value = %f\n", temp_string, input_value);
}
/* use the data */
for(i = 0; i<10; i++){
printf("%f\n",f_array[i]);
/* do something */
}
}
I'm writing a program that scan words from a text file
how can I scan only the word that starts with space or number and end with a space
Without taking ',.()\t\n to my string
I know i can use the function scanf but didn't quite get how to use it that way
Another small question
I'm looking to count how many lines there are in my text
so I guess I should look for a "\n" sign to increase my count right?
First of all when you ask a question you need to follow some rules, here is a like for how to ask questions in stack overflow:
How to ask from the Stack Overflow Help Center
If I was doing this task I would read it char by char using a 'while loop' ends at EOF and inside of it a 'if' checks if you should add this char to your string and adding it using realloc.
For your second question put another 'if' before the first one that checks if the char == to '\n' and if so ++ to a int that count number of lines.
At the end it should look like this:
int *input = malloc(sizeof(int));
int linesLength = 0;
int now;
int lines = 0;
whlie ((now = getc(file)) != EOF){
if (now == '\n') {
lines += 1;
}
if (/* what chars you want out */){
/* add your char using realloc */
linesLength += 1;
}
}
Btw this is the exact same task I need to do till the 18 to this month and your name looks familiar, the point is, this is not a site for homework, pay attention for this next time.
I need to limit the input from a user to only positive values, and count the number of digits in that number. The user will only type in a (+/-) whole number up to 9 characters long.
I'm only allowed to use the scanf function and for, while, or do-while loops.(I saw in similar questions how to do this using getchar, but I can only use scanf). I'm not allowed to use arrays, or any other library besides stdio.h and math.h
I know that if I write:
n=scanf("%c%c%c%c%c",&a,&b,&c,&e,&f);
n will count the number of successful scanf conversions.
The problem i'm having is that when I define the input with char, it does everything I want except that the user MUST enter 5 characters. So if the user wants to input "55" he has to press "5" "5" "enter" "enter" "enter".
I need the program to move on after the first "enter" but also be flexible to receive a number up to 9 digits long.
again, I can't use getchar or anything fancy. Just the really basic stuff in C that you learn in the first 2 weeks.
Use scanf to read the number into a long int , then use a for loop with a /10 to count the number of digits
What do you want the program to do in case of a -ve number being entered?
#include<stdio.h>
int main()
{
long int a;
int b;
do
{
scanf ("%ld",&a);
if(a<0)
printf ("invalid input");
}while(a<0);
for(b=0;a!=0;b++,a=a/10);
printf("%d",b);
}
(does not handle -ve numbers specially)
Something like
#include <stdio.h>
int main(void)
{
char buffer[10] = { 0 };
size_t len;
scanf("%9[0-9]", buffer);
for(len = 0; buffer[len] != 0; len++) ;
printf("%zu '%s'\n", len, buffer);
return 0;
}
works, but I don't know if it fits your need.
EDIT (bits of explanation)
You can replace size_t with int (or unsigned int), though size_t is better. If you do, use %d or %u instead of %zu.
The basic idea is to exploit a feature of the format of scanf; the 9[0-9] says the input is a sequence of up to 9 char in the given set i.e. the digits from 0 to 9.
The for(...) is just a way to count char, a simple implementation of a strlen. Then we print the result.
The approach I would take would be the following.
Loops are allowed, so go ahead and set one up.
You need to have a variable somewhere that will keep track of what the current number is.
Think about typing out a number, one character at a time. What needs to happen to the current_number variable?
You need to stop the loop if a return key has been pressed.
Something like this should do for starters, but I'll leave the rest up to you, specifically what return_check(ch), update_state(current_val) and char_to_int(ch) looks like. Also note that rather than use a function, feel free to put your own function directly into the code.
int current_val=0;
int num_digits=0;
char ch="\0"
for (num_digits=0;return_check(ch) && num_digits<=9;num_digits++)
{
fscanf("%c");
current_val=update_state(current_val);
current_val=current_val+char_to_int(ch);
}
As for the logic in update_state(), think about what happens, one character at a time, if a user types in a number, like 123456789. How is current_val different from a 1 to a 12, and a 12 to a 123.
Can you wrap a loop around it, something like (I don't know if all of the syntax is right):
const int max_size=9
int n=0; //counter for number of chars entered
char a[max_size-1];
do {
scanf(%c,&a[n]);
n++;
} while (a[n] != '\r' && n<max_size)
I know it's a little unorthodox and will probably cost me some downvotes, but since it's due in 1 hour and I have no idea where to begin I thought I'd ask you guys.
Basically I'm presented with a string that contains placeholders in + form, for example:
1+2+5
I have to create a function to print out all the possibilities of placing different combinations of any given series of digits. I.e. for the series:
[9,8,6] // string array
The output will be
16265
16285
16295
18265
18285
18295
19265
19285
19295
So for each input I get (number of digits)^(number of placeholders) lines of output.
Digits are 0-9 and the maximum form of the digits string is [0,1,2,3,4,5,6,7,8,9].
The original string can have many placeholders (as you'd expect the output can get VERY lengthly).
I have to do it in C, preferably with no recursion. Again I really appreciate any help, couldn't be more thankful right now.
If you can offer an idea, a simplified way to look at solving this, even in a different language or recursively, it'd still be ok, I could use a general concept and move on from there.
It prints them in different order, but it does not matter. and it's not recursive.
#include <stdlib.h>
#include <stdio.h>
int // 0 if no more.
get_string(char* s, const char* spare_chr, int spare_cnt, int comb_num){
for (; *s; s++){
if (*s != '+') continue;
*s = spare_chr[comb_num % spare_cnt];
comb_num /= spare_cnt;
};
return !comb_num;
};
int main(){
const char* spare_str = "986";
int num = 0;
while (1){
char str[] = "1+2+5";
if (!get_string(str, spare_str, strlen(spare_str), num++))
break; // done
printf("str num %2d: %s\n", num, str);
};
return 0;
};
In order to do the actual replacement, you can use strchr to find the first occurrence of a character and return a char * pointer to it. You can then simply change that pointer's value and bam, you've done a character replacement.
Because strchr searches for the first occurrence (before a null terminator), you can use it repeatedly for every value you want to replace.
The loop's a little trickier, but let's see what you make of this.