How to Accept Standard Input in C from the Linux Command Line - c

I am trying to accept a string from the standard input in Linux, take the given string and change the 'A'(s) and 'a'(s) to '#', and output the altered string.
In linux I am running this: echo "This problem is an EASY one" | ./a2at
My a2at.c program contains this:
#include <stdio.h>
#include <string.h>
int main(int argc, char *words[])
{
int i = 0;
char b[256];
while(words[i] != NULL)
{
b[i] = *words[i];
if(b[i] =='a' || b[i]=='A')
{
b[i] = '#';
}
printf("%c",b[i]);
}
return 0;
}
Any help would be really appreciated! I know that I am pretty far off from the right code.

You may use getchar() in order to read a single character at a time, or fgets() in order to read a complete line each time.
The easiest solution would be to use getch in a simple infinite loop:
while (1) {
int ch = getchar();
if (ch == EOF) {
break;
} else if (ch == 'a' || ch == 'A') {
putchar('#');
} else {
putchar(ch);
}
}

As #BLUEPIXY said in his comment, you could use getchar function from stdio.h, just do man getchar in your shell to have more details about the usages. This code could help you, but don't hesitate to use the man command :) !
#include <stdio.h>
int main(void)
{
int c;
while ((c=getchar()) && c!=EOF) {
if (c == 'a' || c== 'A')
c = '#';
write(1, &c, 1); // Or printf("%c", c);
}
return (0);
}

Related

Getting garbage value at the end of some strings

I scraped a website to get some mcqs for a c assignment. I wrote the data to a plaintext file separating every entry with null chars.
The pattern is:
Question with choices NULL Answer NULL Question...
Here is a sample of the file. the red dots are '\0' chars:
Here is a link to get the full file.
Code to read this file in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Question{
char question[1000];
char answer;
};
int main(){
struct Question questions[100];
FILE *fp;
char buffer[1000],choice;
int ch,i=0,c=1,k=0,score=0;
fp=fopen("quiz_questions.txt","r");
ch = 1;
while (ch != EOF)
{
ch = getc(fp);
buffer[i]=ch;
i++;
if(ch=='\0'){
buffer[i]='\0';
c++;
i=0;
continue;
}
if(c%2){ //question
strcpy(questions[k].question,buffer);
}
else{ //answer
questions[k].answer=buffer[0];
k++;
}
}
for(i=0;i<35;i++){
printf("\nQuestion:\n%s\nAnswer: %c\n",questions[i].question,questions[i].answer);
}
return 0;
}
OUTPUT:
What am I missing? Help please. It seems the buffer isn't getting null terminated properly and is retaining chars from last assignment.
PS: Is there a better way to consume this data from c? Scraping done via python.
EDIT: I now realize writing a separate answerkey file would have been much better. Stupid me.
strcpy(questions[k].question,buffer);
This statement is executed for every single character you read (if c is odd). At this point, buffer is not null terminated yet (and not a string).
ch = getc(fp);
buffer[i]=ch;
These two lines write to buffer[i] even if the end of file was reached. You only check for EOF after having processed it as if it were a normal character.
i++;
if(ch=='\0'){
buffer[i]='\0';
This is redundant. If ch is '\0', then you've just null terminated buffer in buffer[i]=ch;. There's no need to add another '\0'.
Modified version of your code to solve the problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Question{
char question[1000];
char answer;
};
int main()
{
struct Question questions[100];
FILE *fp;
char buffer[1000],choice;
int ch,i=0,c=0,k=0,score=0; **<-- EDIT:change done here to initialize c = 0**
fp=fopen("quiz_questions.txt","r");
ch = 1;
while (ch != EOF)
{
ch = getc(fp);
buffer[i]=ch;
i++;
if(ch =='\0')
{
//buffer[i]='\0'; <-- Change done here, unnecessary assignment
c++;
i=0;
if(c%2) <-- Change done here, moved inside if (ch == '\0') case
{
//question
strcpy(questions[k].question,buffer);
}
else
{
//answer
questions[k].answer=buffer[0];
k++;
}
}
}
for(i=0;i<35;i++)
{
printf("\nQuestion:\n%s\nAnswer: %c\n",questions[i].question,questions[i].answer);
}
return 0;
}

printing a word per line

I need to write a program that prints its input one word per line. Here's what I got so far:
#include <stdio.h>
main(){
int c;
while ((c = getchar()) != EOF){
if (c != ' ' || c!='\n' || c!='\t')
printf("%c", c);
else
printf("\n");
}
}
The logic is pretty simple. I check to see if the input is not a newline, tab or space, and in that case it prints it, otherwise prints a newline.
When I run it, I get results like this:
input--> This is
output--> This is
It prints the whole thing. What goes wrong here?
if (c != ' ' || c!='\n' || c!='\t')
This will never be false.
Perhaps you meant:
if (c != ' ' && c!='\n' && c!='\t')
instead of using printf try putchar, also as per above comments, you should use && instead of ||.
here is my code-
#include<stdio.h>
main()
{
int c, nw; /* nw for word & c for character*/
while ( ( c = getchar() ) != EOF ){
if ( c != ' ' && c != '\n' && c != '\t')
nw = c;
else {
nw = '\n';
}
putchar (nw);
}
}
this code will give you the desired output
you can use if you want the strtok function in string.h library which can cut the input into many words by providing a delimiter.
Here is a perfect code commented which can fit to your needs
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char line[1000]=""; // the line that you will enter in the input
printf("Input the line:\n>>");
scanf("%[^\n]",line); // read the line till the you hit enter button
char *p=strtok(line," !#$%&'()*+,-./'"); // cut the line into words
// delimiter here are punctuation characters (blank)!#$%&'()*+,-./'
printf("\nThese are the words written in the line :\n");
printf("----------------------------------------\n");
while (p!=NULL) // a loop to extract the words one by one
{
printf("%s\n",p); // print each word
p=strtok(NULL," !#$%&'()*+,-./'"); // repeat till p is null
}
return 0;
}
If we execute the code above we will get
Input the line:
>>hello every body how are you !
These are the words written in the line :
----------------------------------------
hello
every
body
how
are
you
suggest the code implement a state machine,
where there are two states, in-a-word and not-in-a-word.
Also, there are numerous other characters that could be read
(I.E. ',' '.' '?' etc) that need to be check for.
the general logic:
state = not-in-a-word
output '\n'
get first char
loop until eof
if char is in range a...z or in range A...Z
then
output char
state = in-a-word
else if state == in-a-word
then
output '\n'
state = not-in-a-word
else
do nothing
end if
get next char
end loop
output '\n'
I think the simple solution would be like
#include <stdio.h>
int main(void) {
// your code goes here
int c;
while((c=getchar())!=EOF)
{
if(c==' ' || c=='\t' || c=='\b')
{
printf("\n");
while(c==' ' || c=='\t' || c=='\b')
c=getchar();
}
if(c!=EOF)
putchar(c);
}
return 0;
}

Reading a whole line before printing result

Ok firstly I'm a total amateur on programming and i wanted to try something. I want to make a C program which will read a line and then if the characters are accepted to print "ACCEPTED" or "REJECTED" if the characters are valid or not.
So I've used a while loop and some if-else if to add the viable characters. The viable characters are the letters of the alphabet ',' '.' '/' '[' ']'. The problem is that after i type the whole line, it prints ACCEPTED and REJECTED for every character on the line. How can i get the program to read the whole line first and then print the result?
#include <stdio.h>
int main(void) {
char c;
c=getchar();
while(c!=EOF) {
while (c!='\n') {
if (c>='a' && c<='z') {
printf("OK!\n");
}
else if(c==','|| c=='.' ||c=='/') {
printf("OK!\n");
}
else if(c==']'||c=='[') {
printf("OK!\n");
}
else {
printf("ERROR!\n");
}
c=getchar();
}
c=getchar();
}
}
Sorry, my original answer did not seem to relate to your question. Skim reading fail.
Thank you for posting the code, it helps a lot when it comes to answering your question correctly.
Ignoring style for now, I would change your code in this way to make it print OK only when you finish parsing the entire line and it is exactly what #ScottMermelstein said but with code.
#include <stdio.h>
int main(void) {
int c; // This needs to be an int otherwise you won't recognize EOF correctly
int is_ok;
c=getchar();
while(c!=EOF) {
is_ok = 1; // Let's assume all characters will be correct for each line.
while (c!='\n') { // So long as we are in this loop we are on a single line
if (c>='a' && c<='z') {
// Do nothing (leave for clarity for now)
}
else if(c==','|| c=='.' ||c=='/') {
// Do nothing (leave for clarity for now)
}
else if(c==']'||c=='[') {
// Do nothing (leave for clarity for now)
}
else {
is_ok = 0; // Set is_ok to false and get out of the loop
break;
}
c=getchar();
}
if (is_ok) // Only print our result after we finished processing the line.
{
printf("OK!\n");
} else
{
printf("ERROR!\n");
}
c=getchar();
}
return 0; // If you declare main to return int, you should return an int...
}
However, I would recommend modularizing your code a little more. This will come with time and practice but you can write things in a way that is much easier to understand if you hide things away in appropriately named functions.
#include <stdio.h>
int is_valid_char(int c)
{
return (isalpha(c) || c == ',' || c == '.' || c == '/' || c == '[' || c == ']');
}
int main(void) {
int c;
int is_valid_line;
c=getchar();
while(c!=EOF) {
is_valid_line = 1;
while (c!='\n') {
if (!is_valid_char(c)) {
is_valid_line = 0; // Set is_valid_line to false on first invalid char
break; // and get out of the loop
}
c=getchar();
}
if (is_valid_line) // Only print our result after we finished processing the line.
{
printf("OK!\n");
} else
{
printf("ERROR!\n");
}
c=getchar();
}
return 0;
}
You can use scanf and putting a space before the format specifier %c to ignore white-space.
char ch;
scanf(" %c", &ch);
This might be what you are looking for?
Read a line and process good/bad chars and print either OK or Error.
#include <stdio.h>
int main ( void )
{
char buff[1000];
char *p = buff ;
char c ;
int flgError= 0 ; // Assume no errors
gets( buff ) ;
printf("You entered '%s'\n", buff );
while ( *p ) // use pointer to scan through each char of line entered
{
c=*p++ ; // get char and point to next one
if ( // Your OK conditions
(c>='a' && c<='z')
|| (c>='A' && c<='Z') // probably want upper case letter to be OK
|| (c==','|| c=='.' ||c=='/')
|| (c==']'||c=='[')
|| (c=='\n' ) // assume linefeed OK
)
{
// nothing to do since these are OK
}
else
{
printf ("bad char=%c\n",c);
flgError = 1; // 1 or more bad chars
}
}
if ( flgError )
printf ( "Error\n" );
else
printf ( "OK\n" );
}

K&R answer 1-12 (using functions to reduce the number of lines of code)

I have written the following program to answer Kernighan and Ritchies ch1 problem 12.
The issue is that I have never really understood how to properly use functions and would like to know why the one I wrote into this program, getcharc(), does not work?
What are good resources that explain correct function usage. Where? and How?
I know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
#include <stdio.h>
int getcharc ();
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
getcharc(c);
}
while ( c == '\b') {
getcharc(c);
}
while ( c == '\\') {
getcharc(c);
}
while ( c == ' ') {
getcharc(c);
}
putchar(c);
}
}
int getcharc ()
{
int c;
c = getchar();
printf("\n");
return 0;
}
The original program (and I know it has bugs), without the function was:
#include <stdio.h>
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
c = getchar();
printf("\n");
}
while ( c == '\b') {
c = getchar();
printf("\n");
}
while ( c == '\\') {
c = getchar();
printf("\n");
}
while ( c == ' ') {
c = getchar();
printf("\n");
}
putchar(c);
}
}
So all I am trying to do with the function is to stop
c = getchar();
printf("\n");
being repeated every time.
What, exactly, is this getcharc() function supposed to do? What it does, is read a character from input, print a newline, and return zero. The character just read from input is discarded, because you didn't do anything with it. When it's called, the return value is ignored as well. In each of the places where it is called, you're calling it in an infinite loop, because there's no provision made for changing the loop control variable.
Perhaps you were intending something like c = getcharc(), but that wouldn't really help because you aren't returning c from the function, anyway. (Well, it would help with the "infinite loop" part, anyway.)
What's the point of this function anyway? If you just use getchar() correctly in its place, it looks like you'd have your solution, barring a few other bugs.
One of the possible solution is, change prototype for your function to int getcharc (int c, int flag).
Now your code after some modification;
#include <stdio.h>
int getcharc (int c, int flag);
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
int flag = 0; //to keep track of repeated newline chars.
while ((c = getchar()) != '\n') {
flag = getcharc(c, flag); // call getcharc() for each char in the input string. Testing for newline and printing of chars be done in the getcharc() function
}
return 0;
}
int getcharc (int c, int flag)
{
if( (c == ' ' || c == '\t' || c == '\b' || c== '\\') && flag == 0)
{
printf("\n");
flag = 1;
}
else
{
if(c != ' ' && c != '\t' && c != '\b' && c!= '\\')
{
putchar(c);
flag = 0;
}
}
return flag;
}
EDIT:
but I wanted to keep the nested while statements rather than using || or
Your nested while loop is executing only once for each character as grtchar() reads one character at one time. No need of nested loops here! You can check it by replacing while to if and your code will give the same output for a given string. See the output here.
know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
You make your program work to some extent (with your bugs) by adding an if condition and a break statement as;
#include <stdio.h>
int getcharc (int c);
int main()
{
int c;
while ((c = getchar()) != '\n') {
while ( c == '\t') {
c = getcharc(c);
if(c != '\t')
break;
}
....
....
while ( c == ' ') {
c = getcharc(c);
if(c != ' ')
break;
}
putchar(c);
}
return 0;
}
int getcharc (int c)
{
c = getchar();
printf("\n");
return c;
}
// compiled by my brain muhahaha
#include <stdio.h>
int getcharc(); // we prototype getcharc without an argument
int main()
{
int c; // we declare c
// read character from stdio, if end of file quit, store read character in c
while ((c = getchar()) != EOF) {
// if c is tab \t call function getcharc() until forever since c never changes
while ( c == '\t') {
getcharc(c); // we call function getcharc with an argument
// however getcharc doesn't take an argument according to the prototype
}
// if c is \b call function getcharc() until forever since c never changes
while ( c == '\b') {
getcharc(c);
}
// if c is \\ call function getcharc() until forever since c never changes
while ( c == '\\') {
getcharc(c);
}
// if c is ' ' call function getcharc() until forever since c never changes
while ( c == ' ') {
getcharc(c);
}
// since we never will get here but if we happened to get here by some
// strange influence of some rare cosmic phenomena print out c
putchar(c);
}
}
// getcharc doesn't take an argument
int getcharc ()
{
int c; // we declare another c
c = getchar(); // we read from the keyboard a character
printf("\n"); // we print a newline
return 0; // we return 0 which anyway will never be read by anyone
}
maybe you are getting confused with the old K&R
nowadays when you write a function argument you specify it like
int getcharch(int c)
{
...
}

Counting Number of words and Characters in a Sentence using C

I tried the below program .
INPUT-: i want help
Desired OUTPUT-:Words=3 Characters=9
But the actual output deviates from the desired.
Can someone tell what is my mistake .
include
void main()
{
int countch=0;
int countwd=1;
printf("Enter your sentence in lowercase: ");
char ch='a';
while(ch!='\r')
{
ch=getche();
if(ch==' ')
countwd++;
else
countch++;
}
printf("\n Words = ",countwd);
printf("Characters = ",countch-1);
getch();
}
Be advised: getchar() returns int, not char. This is one of the most common pitfalls for beginning C programmers, it seems.
Also, you should check for the special value EOF and stop the program if it occurs; this is the typical and "clean" way of doing programs that read input and will make the program automatically handle both interactive input (from a terminal) and input from a file.
There are few observations which you might find of some use:
1. You are using getch & getche which are both non-standard functions. Make use of getchar instead. In this case as already pointed in unwind's response you need to use int for the return type.
2. Please change the return type of main from void to int.
3. You are not specifying the formats in printf. Please add %d specifier to print integers.
I have not used codepad but ideone allows you to add inputs to your programs. Here is a reference based on your sample on ideone.
Hope this helps!
#include<stdio.h>
#include<stdbool.h>
int main(void)
{
char c = '\0';
int nw = 0,nc = 0,nl = 0;
bool flag = true;
bool last = false,cur = false;
while(flag && (c = getchar())) {
if(c != EOF)
++nc;
else
flag = false;
if(c == '\n') nl++;
cur = (c == EOF || c == ' ' || c == '\t' || c == '\n')?false:true;
if(last && !cur )
++nw;
last = cur;
}
printf("\nNo of chars : %d",nc);
printf("\nNo of lines : %d",nl);
printf("\nNo of words : %d",nw);
return 0;
}

Resources