I am writing some code to check whether a string is a palindrome, but it's giving me a runtime error. I can't spot where the error is. Please help.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char a[20];
int n,c;
c=0;
printf("enter the size of the string ");
scanf("%d",&n);
printf("enter the string ");
fgets(a,n,stdin);
for(int i=0;i<(n-1)/2;i++)
{
if(a[i]==a[n-1-i])
{
c=0;
}
else
{
c=1;
break;
}
}
if(c==0)
printf("string is palindrome");
else
printf("string is not palindrome");
return 0;
}
Well, the first thing I notice, upon compiling and executing this, is
that it doesn’t let you enter the string. This is due to the way you’re
taking input:
printf("enter the size of the string ");
scanf("%d",&n);
printf("enter the string ");
fgets(a,n,stdin);
It runs scanf("%d",&n);. So the user types, say, 6, followed by the
enter key. Hokay, so scanf looks at those characters 6\n, takes the
6, converts to a number, and n ends up with a value of 6.
But that newline is still there. scanf didn’t do anything with it
because it’s not numeric. So, when the code gets to here:
fgets(a,n,stdin);
It then reads that newline and thinks “Okay! The user entered an empty
string.” (Yes I know I’m being anthropomorphic, sue me.)
This sort of behavior is why I avoid using scanf. I would code it this
way:
fgets(a, sizeof(a), stdin);
n = atoi(a);
printf("enter the string ");
fgets(a, sizeof(a), stdin);
Note that this also limits each fgets to the size of the buffer,
avoiding potential buffer overflows. This is an important consideration
with working code, because a buffer overflow can easily lead to a
vulnerability that can be exploited to break security. Best to develop
good habits even with simple learning programs like this.
Note also that a better way to do this would be to simply read the
string by itself, then compute its length with strlen.
At this point, it seems to be working correctly, so I won’t delve into
the rest of it. However, if you take my advice about computing the
length, there’s one more thing to be aware of. If you add this line
(temporarily, just for debugging purposes):
printf("%d\n", strlen(a));
You will see that you have one more character than you expect. That is
because fgets retains the newline. So, we want to get rid of it:
a[strlen(a) - 1] = '\0';
This isn’t necessary if you use the value of n, because then it will
just ignore the newline and use the n characters preceding it. But it
would be necessary if you’re computing the length.
Take a look at this code, that's how I have implemented it (remember to #include <stdbool.h> or it will not work):
for(i = 0; i < string_length; i++)
{
if(sentence[i] == sentence[string_lenght-1-i])
palindrome = true;
else
{
palindrome = false;
break;
}
}
Doing that it will check if your sentence is palindrome and, at the first occurence this is not true it will break the for loop. You can use something like
if(palindrome)
printf(..);
else
printf(..);
for a simple prompt for the user.
Example :
radar is palindrome
abba is palindrome
abcabc is not palindrome
Please , pay attention to the fact that
Abba
is not recognized as a palindrome due to the fact that ' A ' and 'a' have different ASCII codes :
'A' has the value of 65
'a' has the value of 97
according to the ASCII table. You can find out more here.
You can avoid this issue trasforming all the characters of the string to lower case characters.
You can do this including the <ctype.h> library and calling the function int tolower(int c); like that :
for ( ; *p; ++p) *p = tolower(*p);
or
for(int i = 0; str[i]; i++){
str[i] = tolower(str[i]);
}
Code by Earlz, take a look at this Q&A to look deeper into that.
EDIT : I made a simple program (however it's a sample, it can be further optimised and so on, it's just to give you the idea), see if it can help you
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
void LowerCharacters(char *word, int word_lenth);
int main(void){
char *word = (char *) malloc(10);
bool palindrome = false;
if(word == 0)
{
printf("\nERROR : Out of memory.\n\n");
return 1;
}
printf("\nEnter a word to check if it is palindrome or not : ");
scanf("%s", word);
int word_length = strlen(word);
LowerCharacters(word,word_length);
for(int i = 0; i < word_length; i++)
{
if(word[i] == word[word_length-1-i])
palindrome = true;
else
{
palindrome = false;
break;
}
}
palindrome ? printf("\nThe word %s is palindrome.\n\n", word) : printf("\nThe word %s is not palindrome.\n\n", word);
free(word);
return 0;
}
void LowerCharacters(char *word, int word_length){
for(int i = 0; i < word_length; i++)
word[i] = tolower(word[i]);
}
Input :
Enter a word to check if it is palindrome or not : RadaR
Output :
The word radar is palindrome.
Related
I'm a beginner programmer and im trying to solve some exercises and i needed some help with one of them.
The exercise goes like this:
We need to input a string of characters , read it and print out the length of each word.
This is what i did
int main()
{
char str[N+1+1];
int i=0;
int pos=0;
int wordlen=0;
int word[60]={0,};
printf("Please enter the string of characters: ");
gets(str);
while(i<strlen(str))
{
if(!isalpha(str[i]))
{
wordlen=0;
i++;
}
if(isalpha(str[i]))
{
wordlen++;
i++;
pos=i;
}
word[pos]=wordlen;
wordlen=0;;
i++;
}
for(i=0;i<20;i++)
{
if(word[i]==0) // here im just trying to find a way to avoid printing 0's but you can ignore it if you want
{break;}
else
printf("%d ",word[i]);
}
return 0;
}
The problem is that when i try to compile it for example: I input "hi hi hi" its supposed to print 2 2 2 but instead it's printing nothing.
Can i ask for some help?
I failed to follow OP's logic.
Perhaps begin again?
End-of-word
To "count the length of each word", code needs to identify the end of a word and when to print.
Detecting a non-letter and the current word length > 0 indicates the prior character was the end of a word. Note that every C string ends with a non-letter: '\0', so let us iterate on that too to insure loop ends on a final non-letter.
int word_length = 0;
int strlength = strlen(str); // Call strlen() only once
while (i <= strlength) {
if (isalpha(s[i])) {
word_length++;
} else {
if (word_length > 0) {
printf("%d ", word_length);
word_length = 0;
}
}
}
printf("\n");
gets()
gets() is no longer in the C library for 10 years as it is prone to over-run. Do not use it.
we are supposed to use gets. is unfortunate and implies OP’s instruction is out-of-date. Instead, research fgets() and maybe better instruction material.
Advanced
is...() better called as isalpha((unsigned char) s[i]) to handle s[i] < 0.
In general, better to use size_t than int for string sizing and indexing as the length may exceed INT_MAX. That is not likely to happen with OP's testing here.
I'm completely new to programming (1st term in uni) and I can't keep up with my lecturer. At the moment I'm stuck on this exercise (for much more time than I'm willing to admit). I've tried to find help on the internet (in this site and others as well), but I can't, since our lecturer has us use a very simple form of c. I'm not asking necessarily for a complete answer. I'd really appreaciate even some hints about where I'm on the wrong. I understand that it might be really simple for some, that the question might seem ignorant or stupid and I feel bad for not getting what's wrong, but I need to try to understand.
So, what I'm trying to do is use scanf and a do while loop so the user can input characters in an array. But I don't understand why the loop won't stop when the user presses ENTER. There's more to the code, but I'm trying to take it slowly, step by step. (I'm not allowed to use pointers and getchar etc).
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do
{
scanf("%c", &a[i]);
i=i+1;
}
while((i<=50) && (a[i-1]!='\0'));
for(i=0; i<50; i++)
printf("%c", a[i]);
}
There aren't any nul-terminated strings here, but only string arrays.
So, when pressing enter, a[i-1] is \n not \0 (scanf with %c as parameter doesn't nul-terminate the strings, and ENTER is just a non-nul character with code 10 AKA \n)
Then don't print the rest of the string because you'll get junk, just reuse i when printing the string back:
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do
{
scanf("%c", &a[i]);
i=i+1;
}
while((i<sizeof(a)) && (a[i-1]!='\n')); // \n not \0
int j;
for(j=0; j<i; j++) // stop at i
printf("%c", a[j]); // output is flushed when \n is printed
}
Also test with i<50 not i<=50 because a[50] is outside the array bounds (I've generalized to sizeof(a))
Here is another way you can do this.
#include <stdio.h>
// define Start
#define ARRAY_SIZE 50
// define End
// Function Prototypes Start
void array_reader(char array[]);
void array_printer(char array[]);
// Function Prototypes End
int main(void) {
char user_input[ARRAY_SIZE];
printf("Please enter some characters (50 max)!\n");
array_reader(user_input);
printf("Here is what you said:\n");
array_printer(user_input);
return 0;
}
// Scans in characters into an array. Stops scanning if
// 50 characters have been scanned in or if it reads a
// new line.
void array_reader(char array[]) {
scanf("%c", &array[0]);
int i = 0;
while (
(array[i] != '\n') &&
(i < ARRAY_SIZE)
) {
i++;
scanf("%c", &array[i]);
}
array[i + 1] = '\0';
}
// Prints out an array of characters until it reaches
// the null terminator
void array_printer(char array[]) {
int i = 0;
while (array[i] != '\0') {
printf("%c", array[i]);
i++;
}
}
You may try with this code:
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do {
scanf("%c", &a[i]);
i=i+1;
} while(i<50 && a[i-1] != '\n');
a[i] = 0;
for(i=0; a[i] != 0; i++)
printf("%c", a[i]);
}
The function scanf("%c", pointer) will read one character at a time and place it at the pointer location. You are looking for '\0', which is a valid string terminator, but the newline character you get when you press ENTER and that you should be looking for is '\n'.
Also, it is a good idea to terminate the string you have read by adding a '\0' at the end (really a zero). Then use it to stop printing or you may print the "rest" of the contents of an uninitialized char array.
this is my first time using this site as well as learning c programming.
I'm trying to write a code which lets a user type in a sentence and the code prints it back out.
My attempt:
#include<stdio.h>
int main()
{
char array[1000];
printf("Please enter a phrase: ");
int index = 0;
while(array[index]!= '\0')
{
scanf("%c",&array[index]);
++index;
}
index = 0;
while(array[index]!= '\n')
{
printf("%c",array[index]);
++index;
}
}
I can't find the reason to why this code does not work.
You can get expected output using your concept also.. Try something using following code.
#include<stdio.h>
int main()
{
char array[1000];
printf("Please enter a phrase: ");
int index =0;
scanf("%c",&array[index]);
while(array[index]!='\n')
{
scanf("%c",&array[++index]);
}
index=0;
while(array[index]!= '\n')
{
printf("%c",array[index]);
++index;
}
printf("\n");
}
Okay, so first and foremost you'll need to initialize all your array. If you don't, the user input will print along with lots of meaningless garbage.
Secondly, the test portion of your first while loop checks for a null character which will never exist because "array[]" is just a simple character array (not a string) therefore, a call to scanf() doesn't insert the null character at the end. This causes an infinite loop.
Thirdly, your first while loop should be a do-while so that you first read a character, then test the character, otherwise if the "index" variable increments first...
Lastly, I posted the code that i used to get it to run using the method that you chose. However, as an alternative to the method you chose, the c standard library has the gets() function, which will allow you to read an entire line of input and return the string entered (actually it returns a pointer to the character array created but i think you catch my drift), and the puts() function which prints a string pointed to by the pointer used as an argument.
For more info on this problem in general, including gets() and puts(), refer to "C Programming A Modern Approach" by K.N. King, Chapter 13: Strings.I hope this helps.
Happy Coding!! :)
#include <stdio.h>
int main()
{
int index = 0;
char array[1000];
while(index < 1000){
array[index] = '0';
index++;
}
printf("Please enter a phrase: ");
index = 0;
do {
scanf("%c", &array[index]);
} while(array[index] != '\n' && index++ < 1000);
index = 0;
while(index < 1000)
printf("%c", array[index++]);
}
I think your looking for this:
#include<stdio.h>
int main() {
char array[1000];
printf("Please enter a phrase: ");
scanf ("%[^\n]%*c", array);
printf("\n%s", array);
return 0;
}
I'm trying to create a C program on OTP (One Time Pad) encryption. The program takes a string to be encrypted from the user. Then it has to ask for the length of the key before taking the key (in integer). Since I want the program to be 100% correct, I'm putting a constraint on the length of key. As we know, in OTP the length of the key has to be in integers can't exceed the length of the text. So, how can we implement such a filter? I've tried creating the code but it is not working.
Here's the code:
//An Under-Construction program to implement OTP (One time Pad) encryption
#include "stdio.h"
#include "cstring"
#include "ctype.h"
int main()
{
char str[10000], key[10000];
printf("Enter the string:- ");
scanf("%[^\n]", str); //stops scanning when user presses return
int len /* stores the number of digits of the OTP key*/, isalphabet=0;
do
{
printf("What is the length of the key you are entering?:-");
scanf("%d", &len);
if( isalpha(len) ) // Checks if len is a character
{
isalphabet=NULL; //isalphabet becomes NULL if it is a character and not an integer
}
} while (len > strlen(str) || isalphabet == NULL); //reiterate the loop until the conditions are satisfied
for(int i = 0; i < len; i++)
{
printf("%dth digit of Key= ", i+1);
scanf("%d", &key[i]);
}
return(0);
}
I want the program to take only integer value from the user while scanning 'len' and also the value of 'len' shouldn't exceed the length of the string to be encrypted, and reiterate the loop if these conditions aren't satisfied. Can someone point out my mistake and show the the solution? Also, please explain me the reason as to why isn't the code working as it should.
check scanf("%d", len); is there somewhere a & missing? also initialize len
Update:-
sorry for being late,
okk, actually there's few things you need to correct, sorry i didn't point them in first post.
1) correct the header inclusion delimiter. Use <stdio.h> instead of "stdio.h"
2) initialize len = 0
3) flush stdin after you have read. If you really enter a char, the scanf(%d,&len) is not going to clear it/read it. So you will be stuck in an infinite loop as because of a char stucking in stdin. same goes for the last for loop. Fortunately here you will not be stuck, but the loop will finish prematurely.
4) isalphabet=NULL, isalphabet is int, NULL basically a void pointer with 0x0 value, you should assign 0 to an int.
5) So you came inside the loop with isalphabet=0, the number is not a alphabet, you did not touch the isalphabet, and end of while loop, isalphabet==NULL, here perhaps it will run as true and again the while loop starts. So when is the loop breaking condition getting set to isalphabet?
6) Also why use the cstring in c code? why not string.h (but this is more of a personal choice :))
7) correcting the len > strlen( to len >= strlen
I edited a little bit, check if it works
//An Under-Construction program to implement OTP (One time Pad) encryption
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char str[10000], key[10000];
printf("Enter the string:- ");
scanf("%[^\n]", str); //stops scanning when user presses return
int len /* stores the number of digits of the OTP key*/, isalphabet=0;
do
{
printf("What is the length of the key you are entering?:-");
scanf("%d", &len);
fflush(stdin);
if( isalpha(len) ) // Checks if len is a character
{
isalphabet=1; //isalphabet becomes NULL if it is a character and not an integer
}
} while (len >= strlen(str) || isalphabet == 1); //reiterate the loop until the conditions are satisfied
int i;
for(i = 0; i < len; i++)
{
printf("%dth digit of Key= ", i+1);
scanf("%d", &key[i]);
}
return(0);
}
First, scanf("%d", len); should be
scanf("%d", &len);
The strlen(str) returns the length, and the comparison should be
len > (strlen(str) -1)
and the comparisons for if is an alpha or not, could be done inside the while loop.
Check this code.
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#define TRUE 1
#define FALSE 0
int main()
{
char str[10000];
char key[10000];
printf("Enter the string:- ");
scanf("%[^\n]", str); //stops scanning when user presses return
int len = 0;
int isalphabet= TRUE;
int apply = 1;
do
{
printf("What is the length of the key you are entering?:-");
scanf("%d", &len);
isalphabet= isalpha(len);
apply = (len > (strlen(str) -1)) ;
} while (!apply || isalphabet); //reiterate the loop until the conditions are satisfied
int i;
for(i = 0; i < len; i++)
{
printf("%dth digit of Key= ", i+1);
scanf("%c\n", &key[i]);
}
for(i = 0; i < len; i++){
printf("key[%d] = %c\n", i, key[i]);
}
return(0);
}
I'm trying to write a program that counts all the characters in a string. I originally had it, but then realized I can't count spaces. I can't see why this does not work.
for(m=0; z[m] != 0; m++) {
if(z[m] != ' ') {
charcount ++;
}
}
Any assistance appreciated.
Edit* Does it make a difference if the input(strings) are being scanned in like this? And yes, everything is initialized. I've tried printing what z[m] evaluates too and it isn't the actual value of the string at "m", I think this is the problem.
for(j=0; j<7; j++){
printf("Enter a string:\n");
scanf("%s", z);
for(m=0; z[m] != 0; m++){
if(z[m] != ' '){
charcount ++;
}
}
You need to initialize charcount. Other than that, it should work, provided that z is a zero-terminated array of characters and m is an int or similar. I would probably write just z[m] rather than z[m] != 0 (since !0 = true and 0 = false), but both work. There are more efficient ways of doing it (although these days I bet a compiler will handle converting this into a pointer-based loop for you).
Here's a complete, correct example with minimal edits:
const char * z = "testing one two three";
int m;
int charcount;
charcount = 0;
for(m=0; z[m]; m++) {
if(z[m] != ' ') {
charcount ++;
}
}
If you're using a String class of some kind rather than an old-fashioned C null-terminated array, you'll want to look at that class for how to loop through it.
All of the above also assumes you're dealing with ASCII strings. If you're dealing with UTF-encoded strings, you have to handle multi-byte characters.
Re your edit: It makes a big difference: scanf will stop on the first blank (I'd forgotten that). It might make an even bigger difference than that, though, if you're not declaring z correctly. (I'd also recommend using a field width when using scanf for reading strings [or avoiding scanf entirely]; otherwise, you have no control over the number of chars it will try to store, and so in theory, no buffer will ever be big enough to avoid an overflow. More here: http://www.crasseux.com/books/ctutorial/String-overflows-with-scanf.html)
You can use strlen()
I'd suggest using a while loop, and to use more meaningful variable names
m = textIndex
z = text
Something like this would work
while (text[textIndex] != 0x00)
{
textIndex++;
}
Instead of using scanf, try fgets like so:
char input[256];
fgets(input, sizeof(input), stdin);
fgets will read an entire line from a file. As such, passing stdin as the file handle will make it read from standard input, which in most cases will be bound to the console. One thing to watch out for, though, is that the string you get from fgets might include the newline character. Rather than explicitly checking your strings for inequality with the space character (' '), I suggest using the isspace function from ctype.h, which will check for various forms of whitespace (including a regular space and newline).
Here is a complete, runnable example:
#include <stdio.h>
#include <ctype.h>
int count_nonspace(const char* str)
{
int count = 0;
while(*str)
{
if(!isspace(*str++))
count++;
}
return count;
}
int main()
{
char input[256];
fgets(input, sizeof(input), stdin);
printf("%d\n", count_nonspace(input));
}
Yes, there is a difference on input-scan with scanf:
scanf("%s", z);
...
if(z[m] != ' '){
scanf("%s"...) always breaks at space-character, therefore your if ever is true. Better you use fgets to read from stdin,
#define MAXINPUT 80
char line[MAXINPUT];
for(j=0; j<7; j++) {
printf("Enter a string:\n");
if( fgets( line, 80, stdin ) )
{
char *c=line;
if( strchr(line,'\n') ) *strchr(line,'\n')=0;
while( *c )
{
if( *c!=' ' )
++charcount;
++c;
}
}
}
Or if you want WHITE -spaces then take
#include <ctype.h>
...
if( !isspace(*c) )
this seems to work for me, its a simple 30 line code that is in a loop and can detect the letter of choice for the chosen string/sentence/word the user has inputted.
#include <stdio.h>
#include <string.h>
int main(){
while(true){
char string[100];
char letter[100];
int count = 0;
printf("Enter a word/sentence:\n");
scanf(" %[^\n]s",string);
printf("Enter a letter:\n");
scanf(" %c",&letter); //when using scanf for a sentence/word or character, always include a space afterwards.
//Counts each character except space
for(int i = 0; i < strlen(string); i++) {
if(string[i] == letter[0]){
count++;
}
}
//Displays the total number of characters present in the given string
printf("Total number of characters in the string: %d\n", count);
printf("%s\n",string);
}
return 0;
}