C language getchar() and putchar() - c

I'm a new C language learner and I have a problem below, I tried to print name out but it did not print. This is what I tried:
#include <stdio.h>
#include <ctype.h>
int main()
{
char name;
int len = 0;
printf("Enter the user name: ");
name = getchar();
while (name != '\n')
{
len++;
name = getchar();
}
printf("char = %d\n", len);
printf("name = ");
putchar(name);
return (0);
}
output:
Enter the user name: abcd
len = 4
name =
it should print out name = abcd.
I appreciate that and thank you!

getchar() and putchar() can only handle a single character at a time.
Since you need to store a string which is basically a sequence of characters, you need to declare name as a character array.
You can't use putchar() to print a string. Try puts() or printf().
And add a \0 character to denote the end of string when you encounter the '\n' at which point you stop reading.
char name[20];
int len = 0;
printf("Enter the user name: ");
name[len] = getchar();
while (name[len] != '\n')
{
name[++len] = getchar();
}
name[++len]='\0';
If putchar() must be used to print the string, you have the length of the string in len. Make a loop with a variable i=0 and keep iterating as long as i<len while incrementing i by 1
for(i=0; i<len; ++i)
{
putchar(name[i]);
}
You might want to do some error checking to ensure that getchar() worked properly. It will return EOF on error.
And name should be big enough to hold the input string.

getchar() and putchar() handles only single character.
getchar()-
is an input function. It is used to read one character at a time from console input (generally keyboard).
Ex:
char c=getchar();
putchar()-
is an output function. It is used to display one character at a time onto console output (generally monitor). It accepts one argument of character type. Ex:
char c;
putchar(c);
you should use gets() and puts() to work with strings or you can use printf() and scanf()

Learn about the concept of array in C first.
Use scanf() and printf() like below:
#include <stdio.h>
int main(){
char name[20];
printf("Enter the name: ");
scanf("%s", name);
printf("Name: %s", name);
return 0;
}

This is how you can take input and print using getchar() and putchar().
#include <stdio.h>
int main(void)
{
int name;
printf("Enter the user name: ");
while ((name = getchar()) != EOF)
putchar(name);
return 0;
}
I hope this helps. :)

You may need to learn more about programming and about data structures. I would recommend SICP, an excellent and freely available introduction to programming (which is not about C).
You need to learn more of C. Notably about arrays (but they have limitations, I leave you to find out which ones), perhaps struct, pointers, C dynamic memory allocation. That should take you a few weeks, and you need to read several books (and also some reference material like here, perhaps glance also into the specification of C11, i.e. n1570).
(ask yourself what would or should happen if the user of your program entered a name of 50 letters, or even a million ones; and what about "wrong" input, e.g. digits or punctuation? think about what a name really is inside a computer)
Since you are required to only use getchar and putchar, you need to read carefully their specification. Be aware that stdio is often buffering. Perhaps you'll need to use fflush.
Then you could read a name into some data structure (I leave you to find out which ones), and you could read one character at a time using getchar to fill that data structure. Likewise you could output that data structure one character at a time using putchar.
Of course you'll use some control flow primitives (probably some kind of looping).
We won't do your homework.
Don't forget to enable all warnings and debug info in your compiler (e.g. compile with gcc -Wall -Wextra -g if using GCC....). Read documentation about your compiler (e.g. look into the Invoking GCC chapter). Of course, learn how to use the debugger (gdb, see Debugging with GDB)
You are the one starting to learn C programming. Be persevering, it takes some time (weeks or months of work). Read a few books, look into the source code of existing software in C (e.g. free software on github).
PS. For experts on C, doing your homework is trivial; however you should learn by yourself - the purpose of the homework is to teach you something - and if you copy a solution from elsewhere you won't learn anything

Related

Input buffer to get a an input, C programming

I'm in my first steps in C programming, and I came across a task I can not find a solution to.
The task is simple: taking a character from the user.
After that, you receiving a string from the user until the user types the * character.
Then print the number of times the user typed the first character.
I was able to solve the problem using char [SIZE]ת when I placed a maximum input size of 255 bytes (#define SIZE 255).
Nevertheless, my teacher tells me that although the solution is working well, this was not the purpose of the exercise, also, I can not assume a maximum string size.
He asks us to use the input buffer.
No dynamic memory allocation is used in the exercise, and only the stdio.h library is allowed.
I read a lot about the input buffer, but I still have not found the possibility to solve the exercise - how can I absorb value from the user without knowing its size?
I would be happy to receive assistance and tips on how to use the input buffer correctly.
Or more focused, how to input values (string of characters) into the input buffer, and then go over each character separately in this string and process it.
Thank You
There is no need to store all characters. Once you have read a character you can throw it away and just increase a counter. Something like this:
#include <stdio.h>
int main() {
char c, first;
int counter=0;
printf("Enter first character: ");
scanf("%c", &first);
do {
scanf("%c", &c);
if(c == first)
counter++;
} while (c != '*');
printf("You entered '%c' %d times\n", first, counter);
}
Output:
Enter first character: a
aaaaa*
5
or
Enter first character: a
aabbaa*
You entered 'a' 4 times
Note:
As been pointed out in the comments, scanf is not a good tool for this kind of stuff. I would advice against the usage of it, unless you know it is the right tool. But that's beside the point. The point here was to show you that you don't need to store the whole input buffer. If you want to look at alternate input methods (as William Pursell suggested in the comments) you could have a look at fgetc, getc, or getchar for reading single characters. fread is also a tool you should get familiar with.

C: scanf and program exit

I'm trying to learn C programming with some practical exercises.
This one for example should read 2 series of numbers (days of the month) input by the user.
The problem that I'm having is that after the first serie, that works ok, the program skips the other scanf commands and terminates.
Why?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int f = 0;
int days1[31];
int days2[31];
printf("Insert first serie \n");
while(scanf("%d",&days1[f])) {
f++;
}
// the following scanf loop is skipped
f = 0;
printf("Insert second serie \n");
while(scanf("%d",&days2[f])) {
f++;
}
}
thanks
Read documentation of scanf. It returns the number of scanned items, and you should keep and test it. It could return -1 on failure (and that is seen as a true value) then don't consume any input. Its %n conversion specifier is often useful and not enough known.
So code
while(f < 31 && scanf("%d",&days1[f])>0) f++;
But you probably need to end the first series with something which makes scanf fail, and then you need to skip that something. You should define and document a convention about that. Let's pretend that you will type a semicolon ; then you'll code perhaps:
f=0;
while(f < 31 && scanf("%d",&days1[f])>0) f++;
if (getchar() != ';') exit(EXIT_FAILURE);
f=0;
while(f < 31 && scanf("%d",&days2[f])>0) f++;
I'm not sure the above work. You might need to care about spaces or empty lines. You could read each individual line with fgets or getline and parse each line (using sscanf or strtol).
Actually, I would recommend declaring a large enough buffer char buf[256];, use fgets to read a single line containing all the number series, then parse that line using strtol in a loop and caring about the end pointer given to strtol.
You need to document the input format, at least as comments. You could use EBNF notation for that, then use standard parsing techniques.
Of course you should compile with all warnings and debug info (e.g. gcc -Wall -Wextra -g if using GCC...). Then learn to use the debugger (e.g. gdb). It is a necessary skill to have.

Store program.exe has stopped working, How can I resolve it?

I'm trying to compile the following code. When I give input to the program then after pressing enter a popup appears which shows that
store program.exe has stopped working
Note: I am using Windows 8.1
Note: I am working on a program (which used in super stores), which includes the following things:
Product code
Product name
Product price
Total bill calculations
It's just the starting.
#include <stdio.h>
int main (void)
{
int d, code;
char product[100], price[100];
printf("\t\t Welcome to the Metro Store\n\n\n\n Enter your product code: ");
scanf("%d",code);
if(code<100)
printf("Pharmacy\n Name of the Medicine");
fflush(stdout);
fgets(product, 100, stdin);
printf(product);
return 0;
}
For starters you should try
scanf("%d", &code);
You have to tell scanf where to write to. If you don't specify the ampersand (&), scanf will not know where is should write to.
You should read the docs and definitely a good introduction to pointers. If you don't understand pointers, programming in C and C++ is pointless ;-)
Then you can change your fgets() to scanf( "%s", product );
In this case scanf does not need the & because product is short for &product[0]. This can get rather confusing, so get to grips with pointers before continuing.
First, scanf() expects a pointer type variable as as an argument to the format specifier. Use
scanf("%d", &code);
^^
Second, do not mix up scanf() and fgets(). Otherwise, the fgets() will end up only consuming the newline left by scanf("%d"..). Try to use fgets() for taking user input to be on safer side. However, if you have to use both, use something like
scanf("%d", &code);
int ch; while ((ch = getchar())!= EOF && ch != '\n');
fgets(product,100,stdin);
to avoid the issue with the leftover newline.

Is it possible to use scanf("%d" &i) and use the first number inputted only, and nothing else?

First off, I am not familiar with c at all. It would be great if you treated me like a total beginner, which I am.
So, the problem I have is that I don't seem to be able to make it so that the program only takes the information of one number, uses it, then disregards any other information.
At the moment I have something similar to this:
#include <stdio.h>
#include <string.h>
int main(){
int i, ret;
char c, type;
do
{
printf("Convert ASCII # to character\n");
printf("q: Quit.\n");
scanf("%c", &type);
/* I use the " if(type== 'n'); " a number of times. */
/* I left the others out to simplify what my problem is. */
if(type=='1'){
printf("ASCII NUMBER -> CHAR \n");
printf("\t Please input one ASCII code \n");
int ret = scanf("%d", &i);
/* My aim here is to get the amount of integers the user inputs,*/
/* and use that to categorize, but I think I am failing to do so. */
if(ret==1){
printf("\t The character for ASCII code %d is -> '%c' \n\n", i, i);
break;
}
else{
printf("Please input one number./n/n");
break;
}
}
}
while(type=='q');
return 0;
/* A problem I face a lot is where the program would terminate*/
/* even when the while conditions weren't met. */
}
I hope you could understand what I'm trying to do by looking at the code above.
Any help would be greatly appreciated!
the program ends because of the character [enter] left in the input buffer.
You give input value for type then for i and press [enter]. this [enter] is a character left in the input buffer which will be read by next
scanf("%c",type);
so the loop exits. Therefore use getchar() after
int ret = scanf("%d", &i);
To clear the input buffer. and the loop will not end unexpectedly.
Make these changes,
printf("\t Please input one ASCII code \n");
int ret = scanf("%d", &i);
getchar(); //this will read the [enter] character in input buffer
/* My aim here is to get the amount of integers the user inputs,*/
/* and use that to categorize, but I think I am failing to do so. */
if(ret==1){
In general, I find it better to use fgets() (alternatively, if you are using C99, gets_s() -- although I still prefer fgets() for maximum portability to older compiler environments) for all user-based input, then if necessary use sscanf(), strtol(), and the like to convert the string into other data types, as this will read data by line in a way that is buffer-safe and you won't have to worry about things left in the input buffer. This is especially true for user-based input which is never well-formed (due to typos, etc). scanf() really only works well when reading from well-formed input files.
See the comp.lang.c FAQ which describes some of the problems that often occur when using scanf() in detail, including the problem you are seeing above, where inputs seem to be getting skipped:
http://c-faq.com/stdio/scanfprobs.html
http://c-faq.com/stdio/scanfhang.html
http://c-faq.com/stdio/scanfinterlace.html
http://c-faq.com/stdio/scanfjam.html
To find out more about any C standard library function, at a linux command prompt (or Google) type: man 3 fgets and so on.
fgets: http://linux.die.net/man/3/fgets
sscanf: http://linux.die.net/man/3/sscanf
strtol: http://linux.die.net/man/3/strtol
Example:
char buffer[256], type;
fgets( buffer, sizeof(buffer), stdin );
if( sscanf( buffer, "%c", &type ) == 1 ) {
// Was able to read a char from the buffer, now you can use it.
}
else {
// Wasn't able to read a char from the buffer. handle it if required.
}

Whats wrong with my SIMPLE C program?

I am writing a super simple command line based program in C. It's just a small test and the code is very simple. So what it is meant to do is to ask the user for their name, maths grade, english grade, computing grade. Then it figures out their average grade and also tells them the name they entered. Yes I know this is an extremely simple program, but I'm still doing something wrong.
The problem is, one part of my code will run first telling the user to enter their name and then once they do this and press enter the rest of my code will run all at once and then stop working. It's weird I just don't understand what is wrong.
#include <stdio.h>
int main(int argc, const char * argv[])
{
char chr;
char firstname;
int mathsmark, englishmark, computingmark, averagemark;
printf("What is your name?\n");
scanf("%c", &firstname);
printf("\n");
printf("What is your maths mark?\n");
scanf("%d", &mathsmark);
printf("\n");
printf("What is your english mark?\n");
scanf("%d", &englishmark);
printf("\n");
printf("What is your computing mark?\n");
scanf("%d", &computingmark);
printf("\n");
printf("Your name is: %c", firstname);
printf("\n");
averagemark = (mathsmark + englishmark + computingmark) / 3;
printf("%d", averagemark);
printf("\n");
chr = '\0';
while (chr != '\n') {
chr = getchar ();
}
return 0;
}
One major problem is that you've declared firstname to be a single character long, and when you try to read the name from the console, you're using the %c conversion specifier, which reads the next single character from the input stream and stores it to firstname. The remainder of the name is left in the input stream to foul up the remaining scanf calls.
For example, if you type "Jacob" as a first name, then the first scanf call assigns J to firstname, leaving "acob\n" in the input stream.
The next scanf call attempts to convert "acob\n" to an integer value and save it to mathsmark, which fails ("acob\n" is not a valid integer string). Same thing happens for the next two scanf calls.
The last loop
while (chr != '\n')
{
chr = getchar();
}
finally consumes the rest of "acob\n", which contains the newline character (because you hit Enter after typing the name), causing the loop and program to exit.
How do you fix this?
First, you need to declare firstname as an array of char:
char firstname[SOME_SIZE] = {0};
where SOME_SIZE is large enough to handle all your cases. The you need to change scanf call to
scanf("%s", firstname);
This tells scanf to read characters from the input stream up to the next whitespace character and store the results to the firstname array. Note that you don't need to use the & operator here; under most circumstances, an expression of array type will be converted ("decay") to an expression of pointer type, and the value of the expression will be the address of the first element in the array.
Note that scanf is not very safe, and it's not very robust. If you enter more characters than your buffer is sized to hold, scanf will happily store those extra characters to memory following the array, potentially clobbering something important. You can guard against this by using an explicit field width in the conversion specifier, like
scanf(*%29s", firstname);
but in general it's a pain.
scanf is also not very good at detecting bad input. If you enter "12er" as one of your marks, scanf will convert and assign the "12", leaving the "er" in the stream to foul up the next read.
scanf returns the number of successful assignments, so one way to guard against bad input is to check the return value, like so:
if (scanf("%d", &mathmarks) != 1)
{
printf("Bad input detected for math marks\n");
}
Unfortunately, scanf won't remove bad characters from the stream; you'll have to do that yourself using getchar or similar.
This is a common mistake amongst newer C/C++ developers. The scanf function detects you hitting the ENTER/RETURN key to signal the end of input, but it also catches the \n character as well at the end of the input string, so you essentially get two RETURNS being detected.
Please read up on an example of using fgets and sscanf here:
http://www.linuxforums.org/forum/programming-scripting/67560-problem-scanf.html
It will resolve this issue very quickly for you. In the meantime, I strongly urge you to check out this book:
http://www.amazon.com/Primer-Plus-5th-Stephen-Prata/dp/0672326965
It is the most commonly used C programming book in high school and colleges in North America, and has TONS of examples for you to work through, including this specific program you demonstrated above. The print version has more examples than the e-book, so I would just cough up the $30.00 for the printed version.
Good luck!
You might want to look at a few tutorials. Maybe one on Format specifiers and one on strings in C
scanf() reads data from stdin and stores them as specified by the format specifiers. In this case:
char firstname;
scanf("%c", &firstname);
Read 1 character from stdin and store it to firstname:
>> What is your first name?
Mike
Now firstname == 'M' because scanf() read 1 character as we requested.
What you wanted to do was read a string (a bunch of characters):
char firstname[5]; // an array of characters
scanf("%s", firstname); // store as a string
firstname[4] = '\0'; // Truncate the result with a NULL to insure no overflow
>> What is your first name?
Mike
Now firstname is [M][i][k][e][\0] because scanf() read 1 string, as we requested.
Note the same holds true for printf(), a printf with a %c will give you one character where as a printf() with a %s will give you all the characters until the NULL terminator.
You have (at least) two choices.
char firstname[number_big_enough_to_hold_long_name];
/*or */
char *firstname = malloc(sizeof(char) * number_big_enough_to_hold_long_name);
/* ... code ... */
free(firstname);
Further it would be best to limit width of read. scanf() does not know the size (available space) of firstname.
scanf("%number_big_enough_to_hold_long_names", ...
/* i.e. */
char firstname[32];
if(scanf("%31s", firstname) == EOF) {
perror("bad");
return 1;
}
Further you should check if there is anything left before trying next read. I.e. If someone enters "My Name" then only "My" will end up in firstname and "Name" will be left in input stream.
And getchar() returns an int not a char.
getchar
scanf
And search "ansi c char arrays tutorial" or similar.

Resources