i am a starter and i have written a code:
#include<stdio.h>
char c;
char a[100]={0};
int i;
int main(void)
{
while(1)
{
i=0;
while(1){
if((c=getchar())!='\n'){
a[i]=c;
i++;
} else {
break;
}
}
printf("%s\n",a);
}
return 0;
}
and now i have idea that i want to add a break statement that when i type q, the program will break. so my new program is:
#include<stdio.h>
char c;
char a[100]={0};
int i;
int main(void)
{
while(1)
{
i=0;
while(1){
if((c=getchar())!='\n'){
a[i]=c;
i++;
} else {
break;
}
}
printf("%s\n",a);
if(getchar()=='q')break; /*i added this*/
}
return 0;
}
i know because the getchar() conflict the code is not correct, how can i do, to add the type q break command. thanks a lot.
i am a starter and i have written a code
Uh oh! Here goes... Firstly, the odds of successfully learning the portable, standard-compliant C programming language are overwhelmingly low for anyone who tries to learn by unguided trial and error. There's a really nice book you can use as a guide, but you need to read it AND do the exercises as you stumble across them. That's K&R2E, if you're interested.
Anything resembling char c; c = getchar(); is erroneous because the narrowing conversion from int (which getchar returns) to char discards error handling information.
Any character values returned by getchar will be as unsigned char values converted to an int, so it'd technically be more correct (though still incorrect) to use that type.
Error values are returned as a negative integer such as EOF, not to be confused with character values, which is exactly what your code does wrong by discarding the error information.
getchar returns int, so store the value into an int, then test for errors, then, if you must, convert it down to an unsigned char.
and now i have idea that i want to add a break statement that when i type q, the program will break.
Following on from the previous discussion, such a requirement is superfluous, nonetheless easy to incorporate if you're handling errors correctly. Just insert an extra test to match against q into the error handling, and presto!
Nonetheless, the error handling most likely already solves this problem, as most OSes have a mechanism to close stdin, which would cause getchar to return EOF, thus triggering the error handling clause. This is typically achieved by pressing CTRL+d in Linux, or CTRL+z in Windows, for example.
In conclusion, providing you aren't already reading one, it seems a nice book about C isn't all that'd benefit you; a nice book about console scripting for your favourite Unix-like OS would also be highly beneficial.
Unlikely to be what you actually want, but at least this will work
#include<stdio.h>
int main(void)
{
char a[100]={0};
int i = 0;
do {
int c = getchar();
switch (c) {
case EOF:
/*EOF*/
return -1;
case '\n':
a[i] = 0;
printf("%s\n",a);
i= 0;
break;
default:
a[i++] =c;
break;
} while (c != 'q' || i > 1);
return 0;
}
Try this code:
#include <stdio.h>
#include <stdlib.h>
#define q 113 --> These values are coming from ASCII table.
#define Q 81
int main(void)
{
char ch = 0;
do
{
ch = getchar();
switch(ch)
{
case q:
// your logic goes here
exit(0);
case Q:
// your logic goes here
exit(0);
/* more cases can come here */
}
}
while(1);
}
Related
An exercise asked to write a function that:
reads a sequence of alphabetic characters (without memorizing the sequence) that ends only when the users enters '\n'.
returns 1 if the number of capitalized letters went beyond the lower ones of at most an integer m, entered by the user, or 0 else.
I tried with the following code:
#include<stdio.h>
int read(int p,char c)
{
int M=0,m=0,d;
char A,Z,a,z;
while(c != '\n')
{
if(A<=c<=Z)
{
M++;
}
else if(a<=c<=z)
{
m++;
}
scanf("%c",&c);
}
if(M-m>0)
d=(m-M);
else
d=0;
if(d==0)
return 0;
else if (d<=p)
return 1;
}
int main()
{
int a,h;
char k;
scanf("%d", &h);
scanf("%c", &k);
a=read(h,k);
printf("%d\n",a);
return 0;
}
At this point, trying to execute the program with the gcc command, i noticed that the program was taking just the integer, let's say 2, and gave back 0 as if it entered in the function without taking the second scan on the character.
Besides the formal misconception and errors about the program and c function that i'm glad you rectify,
I was trying to understand, because as they say i'm trying to be self-taught, how scanf function and function work in general, when and to who priority is given.
For example in function read it's not clear to me when the value i'm returning to the function are taken putting a higher if as i did.
This isn't going to do what you probably expect
if(A<=c<=Z)
... for all sorts of reasons. Firstly, the values of A and Z are uninitialized. Second, the logic is written to be read by a mathematician, not a C compiler.
You almost certainly wanted this:
if('A'<=c && c<='Z')
... and remove the four variables char A,Z,a,z;
Note that use of character constants such as 'A' and 'Z' assumes a runtime environment using ASCII character sets. If you're interested in a more portable solution, you can look up isupper() and islower()
I have written a small script to detect the full value from the user input with the getchar() function in C. As getchar() only returns the first character i tried to loop through it... The code I have tried myself is:
#include <stdio.h>
int main()
{
char a = getchar();
int b = strlen(a);
for(i=0; i<b; i++) {
printf("%c", a[i]);
}
return 0;
}
But this code does not give me the full value of the user input.
You can do looping part this way
int c;
while((c = getchar()) != '\n' && c != EOF)
{
printf("%c", c);
}
getchar() returns int, not char. And it only returns one char per iteration. It returns, however EOF once input terminates.
You do not check for EOF (you actually cannot detect that instantly when getchar() to char).
a is a char, not an array, neither a string, you cannot apply strlen() to it.
strlen() returns size_t, which is unsigned.
Enable most warnings, your compiler wants to help you.
Sidenote: char can be signed or unsigned.
Read a C book! Your code is soo broken and you confused multiple basic concepts. - no offense!
For a starter, try this one:
#include <stdio.h>
int main(void)
{
int ch;
while ( 1 ) {
ch = getchar();
x: if ( ch == EOF ) // done if input terminated
break;
printf("%c", ch); // %c takes an int-argument!
}
return 0;
}
If you want to terminate on other strings, too, #include <string.h> and replace line x: by:
if ( ch == EOF || strchr("\n\r\33", ch) )
That will terminate if ch is one of the chars listed in the string literal (here: newline, return, ESCape). However, it will also match ther terminating '\0' (not sure if you can enter that anyway).
Storing that into an array is shown in good C books (at least you will learn how to do it yourself).
Point 1: In your code, a is not of array type. you cannot use array subscript operator on that.
Point 2: In your code, strlen(a); is wrong. strlen() calculates the length of a string, i.e, a null terminated char array. You need to pass a pointer to a string to strlen().
Point 3: getchar() does not loop for itself. You need to put getchar() inside a loop to keep on reading the input.
Point 4: getchar() retruns an int. You should change the variable type accordingly.
Point 5: The recommended signature of main() is int main(void).
Keeping the above points in mind,we can write a pesudo-code, which will look something like
#include <stdio.h>
#define MAX 10
int main(void) // nice signature. :-)
{
char arr[MAX] = {0}; //to store the input
int ret = 0;
for(int i=0; i<MAX; i++) //don't want to overrrun array
{
if ( (ret = getchar())!= EOF) //yes, getchar() returns int
{
arr[i] = ret;
printf("%c", arr[i]);
}
else
;//error handling
}
return 0;
}
See here LIVE DEMO
getchar() : get a char (one character) not a string like you want
use fgets() : get a string or gets()(Not recommended) or scanf() (Not recommended)
but first you need to allocate the size of the string : char S[50]
or use a malloc ( #include<stdlib.h> ) :
char *S;
S=(char*)malloc(50);
It looks like you want to read a line (your question mentions a "full value" but you don't explain what that means).
You might simply use fgets for that purpose, with the limitation that you have to provide a fixed size line buffer (and handle - or ignore - the case when a line is larger than the buffer). So you would code
char linebuf[80];
memset (linebuf, 0, sizeof(linbuf)); // clear the buffer
char* lp = fgets(linebuf, sizeof(linebuf), stdin);
if (!lp) {
// handle end-of-file or error
}
else if (!strchr(lp, '\n')) {
/// too short linebuf
}
If you are on a POSIX system (e.g. Linux or MacOSX), you could use getline (which dynamically allocates a buffer). If you want some line edition facility on Linux, consider also readline(3)
Avoid as a plague the obsolete gets
Once you have read a line into some buffer, you can parse it (e.g. using manual parsing, or sscanf -notice the useful %n conversion specification, and test the result count of sscanf-, or strtol(3) -notice that it can give you the ending pointer- etc...).
I am really desperate trying to figure out how can I read char with value -1/255 because for most functions this means EOF. For example if I enter all characters from extended ASCII from low to high (decimal value) I end up with -1/255 which is EOF so I will not get it to array. I created small code to express my problem.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFERSIZE 1024
int main(void){
char c;
unsigned int *array = (unsigned int*)calloc(BUFFERSIZE,sizeof(unsigned int)), i = 0;
while (1){
c = fgetc(stdin);
if (c == EOF)
break;
array[i] = c;
i++;
}
array[i] = 0;
unsigned char *string = (unsigned char *)malloc(i);
for(int j = 0;j < i;j++)
string[j] = array[j];
free(array);
//working with "string"
return 0;
}
I could mode
if (c == EOF)
break;
like this
c = fgetc(stdin);
array[i] = c;
i++;
if (c == EOF)
break;
but ofcourse, program will read control character that user input from keyboard too (for example Ctrl+D - Linux). I tried opening stdin as binary but I found out that posix systems carries all files as binary. I am using QT, GCC and Ubuntu. I tried fread, read, fgets but I ended up the same. Simply said, I need to read everything I enter on stdin and put it into char array except when I enter control character (Ctrl+D) to end reading. Any advices appreciated.
Edit: As noted in the comment by #TonyB you should not declare c as char because fgetc() returns int, so changing it to int c; should make it possible to store EOF in c.
I didn't see that you declared c as char c; so all the credit goes to #TonyB.
Original Answer: Although the problem was addressed in the comments, and I added the solution to this answer, I think you are confused, EOF is not a character, it's a special value returned by some I/O functions to indicate the end of an stream.
You should never assume that it's vaule is -1, it often is but there is a macro for a reason, so you should always rely on the fact that these functions return EOF not -1.
Since there is no ascii representation for the value -1 you can't input that as a character, you can however parse the input string {'-', '1', '\0'}, and convert it to a number if you need to.
Also, Do not cast the return value of malloc().
So I am a very beginner to C programming (I have used Ruby, Python and Haskell before) and I am having trouble getting the most simple thing to work in C (probably because of all the manual memory stuff). Anyway, what I am trying to do is (using simple constructs) make a script that just echoes what the user inputs to the console.
e.g. user inputs hi, console prints hi.
This is what I came up with.
Also, I haven't really mastered pointers, so none of that.
// echo C script
int echo();
int main() {
echo();
return 0;
}
int echo() {
char input[500];
while (1) {
if (scanf("%[^\n]", input) > 0) {
printf("%s\n", input);
}
input[0] = 0;
}
return 1;
}
I realize that there is a bunch of bad practices here, like setting a giant string array, but that is just for simplifying it.
Anyway, my problem is that it repeats the first input then the input freezes. As far as I can tell, it freezes during the while loop (1 is never returned).
Any help would be appreciated.
Oh, and using TCC as the compiler.
You don't need an array for echo
#include <stdio.h>
int main(void)
{
int c;
while((c = getchar()) != EOF) putchar(c);
return 0;
}
It's fine that you have such a large string allocated, as long as it's possible for users to input a string of that length. What I would use for input is fgets (read this for more information). Proper usage in your situation, given that you still would like to use the string of size 500, would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int echo(){
char input[500];
while(fgets(input, 500, STDIN)){ //read from STDIN (aka command-line)
printf("%s\n", input); //print out what user typed in
memset(input, 0, strlen(input)); //reset string to all 0's
}
return 1;
}
Note that changing the value of 500 to whatever smaller number (I would normally go with some power of 2 by convention, like 512, but it doesn't really matter) will limit the length of the user's input to that number. Also note that I didn't test my code but it should work.
scanf("%[^\n]", input
Should be:
scanf("%s",input)
Then after your if you should do:
memset(input,0,500);
There are many ways of accomplishing this task however the easiest would be to read from stdin one byte at a time and output that byte to stdout as you process each byte.
Snippet:
#include <stdio.h>
int main( void ) {
// Iterates until EOF is sent.
for ( int byte = getchar(); byte != EOF; byte = getchar() ) {
// Outputs to stdout the byte.
putchar( byte );
}
return 0;
}
Remark:
You must store the byte that you are reading through stdin in an integer. This is because you are not guaranteed that char is signed or unsigned, there are in fact 3 char types in C (char, signed char and unsigned char). Include the limits library to determine whether a char is signed or not in your environment.
You must compile using the C99 standards, otherwise move the declaration of byte outside of the for loop.
C Program to accept and display "5" characters using getchar() and putchar() functions:
#include<stdio.h>
void main()
{
char ch[6];
ch[0]=getchar();
ch[1]=getchar();
ch[2]=getchar();
ch[3]=getchar();
ch[4]=getchar();
putchar(ch[0]);
putchar(ch[1]);
putchar(ch[2]);
putchar(ch[3]);
putchar(ch[4]);
}
When i am Compiling this code in "C" language then it is displaying this Error message:
"Conversion may lose significant digits", what could be the reason?
getchar returns an int and you're storing it in a char.
You can fix this by changing char ch[6]; to int ch[6];.
getchar() returns an int, to allow for passing additional values which are not in the range of valid characters. This allows for failures and error codes to be returned as values without overloading a particular character with multiple meanings. In normal operation any valid character may be returned, in error operation an int that is too large to fit in a char is returned.
The warning message indicates that you are going to only look at the char portion of the returned value, and as such, you might oddly cast an error or special return value into a char that wasn't actually captured.
--- Edited at the request of gautham to demonstrate good error detection ---
The lack of error checking for input failure can be fixed in one of two ways. The firs one is more common, and works on all systems where the size of an integer is greater than the size of a character.
// an ok approach which works for most systems
// provided that sizeof(int) != sizeof(char)
int c = getchar();
if (EOF != c) {
ch[0] = (char)c;
} else {
// some error occurred during input capture
// which resulted in getchar returning EOF
}
The second solution to error checking for input failure doesn't rely on the size of an integer being larger than the size of a character. It will work on all systems.
// a better approach which works for all systems
// even where sizeof(int) == sizeof(char)
c = getchar();
if (!feof(stdin) && !ferror(stdin)) {
// even if c was EOF, we know it's a char value, not an error value
ch[0] = c;
} else {
// c's value is EOF because of an error capturing the input, and
// not because a char value equaling EOF was read.
}
putting it all together to rewrite your program
#include<stdio.h>
int main(int argc, char** argv)
{
char ch[6];
ch[0]=getchar();
ch[1]=getchar();
ch[2]=getchar();
ch[3]=getchar();
ch[4]=getchar();
putchar(ch[0]);
putchar(ch[1]);
putchar(ch[2]);
putchar(ch[3]);
putchar(ch[4]);
return 0;
}
or if you have been introduced to procedures, the much better version of the above
#include<stdio.h>
char getInput() {
int c = getchar();
if (!feof(stdin) && !ferror(stdin)) {
return (char)c;
} else {
exit(EXIT_FAILURE);
}
}
int main(int argc, char** argv)
{
char ch[6];
ch[0]=getInput();
ch[1]=getInput();
ch[2]=getInput();
ch[3]=getInput();
ch[4]=getInput();
putchar(ch[0]);
putchar(ch[1]);
putchar(ch[2]);
putchar(ch[3]);
putchar(ch[4]);
return 0;
}
and if you have learned a bit about looping, it can be rewritten with a loop like so
#include<stdio.h>
char getInput() {
int c = getchar();
if (!feof(stdin) && !ferror(stdin)) {
return (char)c;
} else {
exit(EXIT_FAILURE);
}
}
int main(int argc, char** argv)
{
char ch[6];
int index;
for (index = 0; index < 5; index++) {
ch[index] = getInput();
}
for (index = 0; index < 5; index++) {
putchar(ch[index]);
}
return 0;
}
There are other checks you might want to add, like checking to see if your putchar failed due to an error during output; but, if you don't have an alternative means of presenting the error (like writing it to a file) then adding such checks only increase the complexity of the code without providing a means of communicating the error to the end user.
Error checking is one of the most important items in writing robust programs, but in most programming courses it is treated very lightly (if it is covered at all). If you don't get much discussion about error checking, do yourself a favor and independently read over <errno.h>. A decent description of how to handle errors in C can be found in the GNU pages disussing error handling. A basic "print to stderr" error handler might look like
// this defines errno
#include <errno.h>
// this defines perror
#include <stdio.h>
// this defines strerror
#include <string.h>
extern volatile int errno;
void printError(int value) {
perror(strerror(value));
}