The Question is to take three names as input and check whether the 4th input is the first letter of one of those three names.
*It needs to be only of alpha type and no other.
Sample Input:
#ON SNOW
ARYA STARK
HODOR
#
Output:
NO
My code:
#include <stdio.h>
#include <ctype.h>
int main(){
char s1[100],s2[100],s3[100];
char ch[1];
scanf("%[^\n]s",s1);
scanf("%[^\n]s",s2);
scanf("%[^\n]s",s3);
scanf("%s",ch);
if(isalpha(ch[0]) && (s1[0]==ch[0] || s2[0]==ch[0] || s3[0]==ch[0]))
printf("yes");
else
printf("no");
}
As I figured out that gets() no longer works, I tried scanf("%s",s1);.
But since it does not store the calude after the whitespace " ", I tried this scanf("%[^\n]s",s1);. But the scanning stops at the first name itself.
John Player
NO
What is the way to store multiple strings in a char array without using loops and only using branching??
Now before getting to the specified problem lets see what the actual problem is:
Problem with scanf()
The problem with scanf() is that it is really bad at managing overflows. And in case of chars or char sequences the newline character is read on the press of enter key in the subsequent scanning. There are numerous instances on SO that concern this problem. scanf() leaves the new line char in buffer? and Problems with scanf
Problem with gets()
The biggest drawback is that here you need to know the size of input before-hand. If you know your input extremely well, you may use it (Still I won't recommend). Why is the gets function so dangerous that it should not be used?
Problem with fgets()
There are two really common problems with fgets()
The syntax of fgets() is:
char *fgets(char *restrict s, int n, FILE *restrict stream);`
and generally used like
fgets(char_array,100,stdin)
First problem arises when the input is bigger than the integer n provided in the fgets() second parameter. When the input in the buffer is bigger than n it will strip off 1st n chars and allocate it the char pointer which might be a char array. But what about remaining chars? They still are there in the input buffer and will be allocated to next fgets(). Messing things up.
Second problem is that every time a new line feed is allocated to the end of char sequence when the input is smaller than the int n-1.
But if we think for a while the problems with fgets() can be tackled with a simple trick.
Just check for the last character in the char sequence which has been recently allocated. If it is new line, replace it by NULL. Else we know that the input was more than that int provided inside fgets(). So all we have to do is eat up the remaining chars in the input buffer.
Here is an example:
char str1[5];
char str2[5];
fgets(str1,5,stdin);
if(strlen(str1)>0){//to avoid Undefined Behavior in case of null byte input
if(str1[strlen(str1)-1]=='\n'){
str1[strlen(str1)-1]='\0';
}
else{
while((getchar())!='\n');//eating the remaing chars in the buffer
}
}
fgets(str2,5,stdin);
if(strlen(str2)>0){
if(str2[strlen(str2)-1]=='\n'){
str2[strlen(str2)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
printf("\n1.%s\n2.%s",str1,str2);
You could even convert strings you got using fgets to float and integers using things like strol or sscanf, but beware they may not show independent behavior.
Now coming back to the solution to your problem:
#include <stdio.h>
#include <string.h>
int main(){
char s1[100],s2[100],s3[100];
char ch[2];//make ch atleast 2 char wide
fgets(s1,100,stdin);
if(strlen(s1)>0){
if(s1[strlen(s1)-1]=='\n'){
s1[strlen(s1)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
fgets(s2,100,stdin);
if(strlen(s2)>0){
if(s2[strlen(s2)-1]=='\n'){
s2[strlen(s2)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
fgets(s3,100,stdin);
if(strlen(s3)>0){
if(s3[strlen(s3)-1]=='\n'){
s3[strlen(s3)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
fgets(ch,2,stdin);
if(strlen(ch)>0){
if(ch[strlen(ch)-1]=='\n'){
ch[strlen(ch)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
if(isalpha(ch[0]) && (s1[0]==ch[0] || s2[0]==ch[0] || s3[0]==ch[0]))
printf("yes");
else
printf("no");
return 0;
}
Try fgets.
fgets(s1,100,stdin);
fgets(s2,100,stdin);
fgets(s3,100,stdin);
#include <stdio.h>
int main(){
char s1[100],s2[100],s3[100];
char ch[1];
fgets(s1,100,stdin);// like gets but limited by length
fgets(s2,100,stdin);
fgets(s3,100,stdin);
scanf("%s",ch);
if( (s1[0]>='a' && s1[0]<='z') || (s1[0]>='A' && s1[0]<='Z') ){//ch-alpha?
if(s1[0] == ch[0]){ printf("yes"); }//s1[0] == ch[0] ??
else{ printf("no"); }
}
else
printf("no"); return 0; }
Related
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...).
#include<stdio.h>
#include<ctype.h>
#include<stdbool.h>
#include<string.h>
#define number_of_letters 26
bool IsPangram(char* string);
int main(){
char check[100];
when i put the output as "the quick brown fox jumps over the lazy dog" the output is no a pangram
and when i put a to z values on one single line is gives the correct output
scanf("%s",&check);
if(IsPangram(check)){
printf("the string entered is pangram");
}
else{
printf("not a pangram");
}
return 0;
}
there is the function for pangram
bool IsPangram(char* string){
bool flags[number_of_letters];
int size=strlen(string);
bool ispangram=true;
int i;
char c;
// for all the alfabets to be setting them to false
for(i=0;i<number_of_letters;i++){
flags[i]=false;
}
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]);
if(islower(c)){
flags[string[i]-'a']=true;
}
}
// for checking the the lettters to no pangram
for(i=0;(i<number_of_letters && ispangram==true);i++){
if(flags[i]==false){
ispangram=false;
}
}
return ispangram;
}
You don't need use & when passing a string as a char *, since arrays decay to pointers when passed as parameters.
So:
scanf("%s",&check);
should be:
scanf("%s", check);
And some general advice: turn on compiler warnings to help catch simple mistakes such as this, and learn basic debugging techniques (stepping through code in your debugger, adding strategic printf statements, etc).
scanf() with the %s format specifier will stop at whitespace. Try fgets(check,100,stdin) instead... that will read (up to) a full line, and limit the number of characters to 99 + nul so you won't exceed the size of check. It may leave a newline as the last character, but your algorithm would ignore that anyway.
Additionally, in IsPangram(), c should be an int instead of a char (to match tolower() etc.), and change this:
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]);
if(islower(c)){
flags[string[i]-'a']=true;
}
}
...to this:
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]); /* <== c will always be lowercase */
if(isalpha(c)){ /* <== Check that c is a letter */
flags[c-'a']=true; /* <== use c, as string[i] may be uppercase */
}
}
...for the reasons indicated in the added comments.
scanf cannot get strings with spaces. So use fgets
fgets(check,sizeof(check),stdin);
Or use
scanf("%[^\n]s",check);
This reads a string till a newline character is encountered.
The default scanf stops reading when a space is encountered.
Here you go:
#include <ctype.h>
void uc(char*s){for(;*s;*s=toupper(*s),s++);}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char*argv[])
{int i,j,n=0,c[256]={0};
char*s,*w[1024]={NULL};
do w[n]=malloc(1024),fgets(w[n],1024,stdin),w[n][strlen(w[n])-1]='\0',uc(w[n]),n++;
while(n<1024&&strlen(w[n-1]));
for(--n,i=0;i<n;++i)
for(j=0;j<strlen(w[i]);++j)
c[w[i][j]]=1;
for(j=0,i='A';i<='Z';++i)j+=c[i];
printf("It's %sa pangram\n",j==26?"":"not ");
for(i=0;i<=n;free(w[i++]));}
I am currently learning C, and so I wanted to make a program that asks the user to input a string and to output the number of characters that were entered, the code compiles fine, when I enter just 1 character it does fine, but when I enter 2 or more characters, no matter what number of character I enter, it will always say there is just one character and crashes after that. This is my code and I can't figure out what is wrong.
int main(void)
{
int siz;
char i[] = "";
printf("Enter a string.\n");
scanf("%s", i);
siz = sizeof(i)/sizeof(char);
printf("%d", siz);
getch();
return 0;
}
I am currently learning to program, so if there is a way to do it using the same scanf() function I will appreciate that since I haven't learned how to use any other function and probably won't understand how it works.
Please, FORGET that scanf exists. The problem you are running into, whilst caused mostly by your understandable inexperience, will continue to BITE you even when you have experience - until you stop.
Here is why:
scanf will read the input, and put the result in the char buffer you provided. However, it will make no check to make sure there is enough space. If it needs more space than you provided, it will overwrite other memory locations - often with disastrous consequences.
A safer method uses fgets - this is a function that does broadly the same thing as scanf, but it will only read in as many characters as you created space for (or: as you say you created space for).
Other observation: sizeof can only evaluate the size known at compile time : the number of bytes taken by a primitive type (int, double, etc) or size of a fixed array (like int i[100];). It cannot be used to determine the size during the program (if the "size" is a thing that changes).
Your program would look like this:
#include <stdio.h>
#include <string.h>
#define BUFLEN 100 // your buffer length
int main(void) // <<< for correctness, include 'void'
{
int siz;
char i[BUFLEN]; // <<< now you have space for a 99 character string plus the '\0'
printf("Enter a string.\n");
fgets(i, BUFLEN, stdin); // read the input, copy the first BUFLEN characters to i
siz = sizeof(i)/sizeof(char); // it turns out that this will give you the answer BUFLEN
// probably not what you wanted. 'sizeof' gives size of array in
// this case, not size of string
// also not
siz = strlen(i) - 1; // strlen is a function that is declared in string.h
// it produces the string length
// subtract 1 if you don't want to count \n
printf("The string length is %d\n", siz); // don't just print the number, say what it is
// and end with a newline: \n
printf("hit <return> to exit program\n"); // tell user what to do next!
getc(stdin);
return 0;
}
I hope this helps.
update you asked the reasonable follow-up question: "how do I know the string was too long".
See this code snippet for inspiration:
#include <stdio.h>
#include <string.h>
#define N 50
int main(void) {
char a[N];
char *b;
printf("enter a string:\n");
b = fgets(a, N, stdin);
if(b == NULL) {
printf("an error occurred reading input!\n"); // can't think how this would happen...
return 0;
}
if (strlen(a) == N-1 && a[N-2] != '\n') { // used all space, didn't get to end of line
printf("string is too long!\n");
}
else {
printf("The string is %s which is %d characters long\n", a, strlen(a)-1); // all went according to plan
}
}
Remember that when you have space for N characters, the last character (at location N-1) must be a '\0' and since fgets includes the '\n' the largest string you can input is really N-2 characters long.
This line:
char i[] = "";
is equivalent to:
char i[1] = {'\0'};
The array i has only one element, the program crashes because of buffer overflow.
I suggest you using fgets() to replace scanf() like this:
#include <stdio.h>
#define MAX_LEN 1024
int main(void)
{
char line[MAX_LEN];
if (fgets(line, sizeof(line), stdin) != NULL)
printf("%zu\n", strlen(line) - 1);
return 0;
}
The length is decremented by 1 because fgets() would store the new line character at the end.
The problem is here:
char i[] = "";
You are essentially creating a char array with a size of 1 due to setting it equal to "";
Instead, use a buffer with a larger size:
char i[128]; /* You can also malloc space if you desire. */
scanf("%s", i);
See the link below to a similar question if you want to include spaces in your input string. There is also some good input there regarding scanf alternatives.
How do you allow spaces to be entered using scanf?
That's because char i[] = ""; is actually an one element array.
Strings in C are stored as the text which ends with \0 (char of value 0). You should use bigger buffer as others said, for example:
char i[100];
scanf("%s", i);
Then, when calculating length of this string you need to search for the \0 char.
int length = 0;
while (i[length] != '\0')
{
length++;
}
After running this code length contains length of the specified input.
You need to allocate space where it will put the input data. In your program, you can allocate space like:
char i[] = " ";
Which will be ok. But, using malloc is better. Check out the man pages.
The below code tries to manipulate several lines of text one at the time.
1.My first issue is to write a loop to read several lines of text(using scanf()) and quit when the first character typed is a newline. These lines of text have some conditions: The first character must be a number between 2 and 6 followed by a space and a line of text(<80).This number will make "dance" the text.
2.My second issue is to figure out how to convert the letters from small to capital and viceversa according to the first number typed. I have to function to make these conversions but I don't know how to call them to change the text.For example: if I typed "3 apples and bananas" the correct output should be "AppLes And BanNas".As you see, the white spaces are ignored and the text always start with a capital letter.
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
using namespace std;
void print_upper(string s1);
void print_lower(string s2);
void main(void)
{
char text[80];
text[0]='A';//Initialization
int count_rhythm;
while (text[0] != '\n'){//To make the loop run until a newline is typed
scanf(" %79[^\n]",text);
if(isdigit(text[0])) //To verify that the first character is a number
{
printf("\nGood");//Only to test
}
else
{
printf("\nWrong text\n");//Only to test
}
}
}
void print_upper(string s1)//Print capital letters
{
int k1;
for(k1=0; s1[k1]!='\0'; ++k1)
putchar(toupper(s1[k1]));
}
void print_lower(string s2)//Print small letters
{
int k2;
for(k2=0; s2[k2]='\0'; ++k2)
putchar(tolower(s2[k2]));
}
You could also define a function printNthUpper() which would take a string and and integer n that would specify which characters to print in upper case. The of the function would be a loop similar to the functions you already have, but with a conditional that compares the provided integer value and the index of a given letter to decide whether to
call toupper() (e.g. printf("%c", i%n == 0 ? toupper(s[i]) : s[i]);).
to write a loop to read several lines of text you can use condition based infinite loop in combination with fgets rather than using scanf.
char line[80];
char result[80]
while(1)
{
fgets(line,sizeof(line),stdin); //read line with fgets
puts(line);
if(line[0]=='\n')
break;
if((strlen(line)>=4) &&'2'< =line[0] && line[0] <= '6' && line[1]==' ')
{
strcpy(result,change_case_of_nth_char(line));// call change case of nth letter
}
else
{
//prompt user to enter input again
}
}
char *change_case_of_nth_char(char *str)
{
}
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.