I'm trying to create a program that checks if a given array/string is a palindrome or not and its not working. The program just prints "0" on every given array, even on palindromes.
int main()
{
char string[100]= {0};
char stringReverse[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
strcpy(stringReverse , string); // This function copies the scanned array to a new array called "stringReverse"
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// This while reverses the array and insert it to a new array called "stringReverse"
while(firstLetter < lastLetter)
{
temp = stringReverse[firstLetter];
stringReverse[firstLetter] = stringReverse[lastLetter];
stringReverse[lastLetter] = temp;
firstLetter++;
lastLetter--;
}
printf("%s %s", stringReverse, string);
if ( strcmp(stringReverse , string) == 0)
{
printf("1");
}
else
{
printf("0");
}
}
Lets say we implement a simple fun to do that
int check_palindrome (const char *s) {
int i,j;
for (i=0,j=strlen(s)-1 ; i<j ; ++i, --j) {
if (s[i] != s[j]) return 0; // Not palindrome
}
return 1; //Palindrome
}
I think this is far more simpler ;)
For the code posted in question:
Be aware of fgets(). It stops in the first '\n' or EOF and keeps the '\n' character.
So if you give radar for ex, the result string will be "radar\n", which doesn't match with "\nradar"
The Problem:
Let's say you enter the string RACECAR as input for your program and press enter, this puts a newline character or a '\n' in your buffer stream and this is also read as part of your string by fgets, and so your program effectively ends up checking if RACECAR\n is a palindrome, which it is not.
The Solution:
After you initialize lastLetter to strlen(string) - 1 check if the last character in your string (or the character at the lastLetter index is the newline character (\n) and if so, decrease lastLetter by one so that your program checks if the rest of your string (RACECAR) is a palindrome.
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// Add these 2 lines to your code
// Checks if the last character of the string read by fgets is newline
if (string[lastLetter] == '\n')
lastLetter--;
fgets adds a '\n' at the end.
So if the user entered "aba", string contains "aba\n".
reverseString contains "\naba".
So it doesn't match.
After the fgets, add this code
int l = strlen(string) - 1;
string[l] = 0;
This will strip out the '\n' at the end before copying it to reverseString.
That aside, you can do this whole program inplace without the need of a second buffer or strcpy or strlen calls.
You have several issues in your code:
first you forgot the last closing brace };
then you forgot to remove the trailing \n (or maybe also \r under Windows) in string;
you don't need to revert the string into a new string; a one-pass check is enough:
Here is a working code:
#include <stdio.h>
#include <string.h>
int main()
{
char string[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
while ((string[lastLetter]=='\n')||(string[lastLetter]=='\r')) {
lastLetter--;
}
// This while reverses the array and insert it to a new array called "stringReverse"
temp = 1;
while(firstLetter < lastLetter)
{
if (string[firstLetter] != string[lastLetter]) {
temp = 0;
break;
}
firstLetter++;
lastLetter--;
}
if ( temp )
{
printf("1");
}
else
{
printf("0");
}
}
You can do it by this simpleway also.
#include <stdio.h>
#include <string.h>
int main()
{
char string[10], revString[10];
printf("Enter string for reversing it...\n");
scanf("%s", string);
int stringLength = strlen(string);
for(int i = 0; string[i] != '\0'; i++, stringLength--)
{
revString[i] = string[stringLength - 1];
}
if(strcmp(string, revString) == 0)
printf("Given string is pelindrom\n");
else
printf("Given string is not pelindrom\n");
}
#include<stdio.h>
#include<string.h>`enter code here`
void fun(char *a);
int main ()
{
char p[100];
char *s=p;
printf("enter the string");
scanf("%[^\n]",s);
fun(s);
}
void fun(char *a)
{
if(*a && *a!='\n')
{
fun(a+1);
putchar(*a);
}
}
// use this approach better time complexity and easier work hope this helps
Related
This is a word guessing game. For example, hello is given as h___o and the user must guess the letters.
I set a condition on my loop but don't know why it is not breaking the while loop.
#include <stdio.h>
#include <string.h>
int main()
{
char word[] = "hello";
int length = strlen(word);
int check;
char spaceLetters[length];
int i, j;
spaceLetters[0] = word[0];
char *dash = "_";
for (i = 1; i < length; i++)
{
strncat(spaceLetters, dash, 1);
}
int attemptLeft = length;
printf("\n %s\n", spaceLetters);
printf("\t\t\tAttempt Left: %d\n", attemptLeft);
boolean start = T;
int userInput;
while (1)
{
printf("\n");
printf("Enter Letter:");
scanf("%c", &userInput);
for loop for checking entered letter is true or not
for (j = 1; j < length;j++)
{
if (word[j] == userInput)
{
spaceLetters[j] = word[j];
printf("%s\n", spaceLetters);
printf("\t\t\tAttempt Left: %d\n", attemptLeft);
printf("\n");
}
}
this is my break loop condition when hello == hello break loop
if(word == spaceLetters){
break;
}
}
}
Strings are represented by arrays/pointers. They need to be compared using string library. Replace
if ( word == spaceLetters )
with
if ( strcmp ( word, spaceLetters ) == 0 )
You'll also need to add #include <string.h>.
For starters instead of this call
scanf("%c", &userInput);
^^^
you have to use this call
char userInput;
//...
scanf(" %c", &userInput);
^^^^
Otherwise the call will read also white spaces as the new line character '\n' that is stored in the input buffer after pressing the Enter key by the user.
Arrays do not have the comparison operator ==. You have to compare arrays element by element. To compare strings stored in character arrays you should use the standard function strcmp
#include <string.h>
//...
if( strcmp( word, spaceLetters ) == 0 ){
break;
}
But before using this function the array specialLetters must be declared like
char spaceLetters[sizeof( word )] = ""`;
That is the array shall contain a string.
Otherwise this for loop in your program invokes undefined behavior.
for (i = 1; i < length; i++)
{
strncat(spaceLetters, dash, 1);
}
And it does not make a great sense.
You could just write
char dash = '_';
memset( spaceLetters + 1, dash, sizeof( spaceLetters ) - 2 );
My code provides the following parameters requested by the teacher:
But the teacher also wants this: "insertChar function should not overwrite any characters. It should insert the new character and offset remaining characters by one index."
how can I set this up? I mean how can I shift a string right from a certain point?
#include<stdio.h>
#include<string.h>
void insertChar(char string[], char c, int index) {
int len = 0;
int i;
for (i = 0; i > index; i--) {
string[i] = len;
string[i] = string[i-1];
string[i-1] = len;
}
string[index] = c;
}
int main() {
char string[100];
printf("Please input a string \n");
scanf ("%[^\n]%*c", string);
printf("Please input the character to be added to string.\n");
char c;
scanf ("%c", &c);
printf("Please input the index which the function will insert the character. \n");
int index;
scanf("%d", &index);
insertChar(string, c, index);
printf("%s", &string);
return 0;
}
How can I shift right after a certain point in the string?
(OP's insertChar() is too broken for repair.)
Watch out for 2 pitfalls: inserting well past the end of the string and exceeding the size of the buffer:
#include <string.h>
void insertChar(size_t buffer_size, char string[], char c, size_t index) {
size_t size_used = strlen(string) + 1;
if (size_used >= buffer_size) {
fprintf(stderr, "Buffer too small for insertion or existing string.");
} else if (index >= size_used) {
fprintf(stderr, "Inserting well past the end of the string.");
} else {
// Move the right portion of the string by 1 with memmove
// v----------------v Address one past the insertion point
memmove(&string[index + 1], &string[index], size_used - index);
// ^------------^ Insertion location
string[index] = c; // Insert
}
}
Usage
char string[100];
...
insertChar(sizeof string, string, c, index);
This lab is trying to show the use of coder-defined functions to execute the code, but I'm trying to do it alternatively so when we actually are tested on it I won't be freaking out that I just copied the source code.
#define NotFound -1
#define WordSize 20
int stringSearch(char * string, char array, int * letter);
int main(void)
{
char * string = (char *) malloc(WordSize * sizeof(char));
char tester = '\0';
int index_tester = 0, i;
// do
// {
// printf("Enter a test string and character, enter q for the test string to exit.\n");
// printf("Test string: ");
// scanf("%s", string);
// while (getchar() != '\n') {}
// if (strcmp(string, "q") == 0) {
// break;
// }
// } // ----> Is it possible to do a while or for look instead? loop here?
printf("What is the test string you wish to enter: ?");
for (i = 0; i < sizeof(string); i++)
{
{
scanf("%c", &string[i]);
}
}
string[i] = '\0';
puts(string);
printf("Tester for the inputed string: ");
scanf("%c", &tester);
while (getchar() != '\n') {}
int ResultofSearch = stringSearch(string, tester, &index_tester);
if (ResultofSearch == NotFound)
{
printf("That letter is not foudn in the string, try again: ");
}
else {
printf("Character found at index %d.\n\n", index_tester);
}
return 0;
}
int stringSearch(char * string, char array, int * letter)
{
for (int i = 0; i < strlen(string); i++)
{
if (string[i] == array)
{
*letter = i;
return (Found);
}
}
return(NotFound);
}
When executing the code, I can put in the string, which I think is working fine, but it will automatically put in the search for some random letters immediately without prompting for the user input. I'm still a greenhorn to all this coding stuff so sorry in advance, any advice would be appreciated though
Apart from the issues pointed out in the comments there is some things you should improve:
char * string = (char *) malloc(WordSize * sizeof(char)); is the same as char * string = malloc(WordSize), but for a 20 word string we will need char * string = malloc(WordSize + 1)
This part of the code:
for (i = 0; i < Wordsize; i++) // already corrected
{
{
scanf("%c", &string[i]);
}
}
string[i] = '\0';
This will obligate you to always have a 19 character string. The cycle will not end until you do (you replace the 20th character with the null-terminator).
You can replace the whole thing with:
fgets(string, WordSize + 1, stdin);
And for good measure, discard the extra characters when the input is too big to fit the string.
int c;
while((c = fgetc(stdin)) !='\n' && c =! EOF); //discard until newline, for completion check for EOF return
This will allow a 20 character max size string but also for smaller ones.
Working sample
You should add required headers, use fgets() rather than scanf() and set tester_index to -1 rather than 0 which means found at index 0.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Found 1
#define NotFound 0
#define WordSize 20
int stringSearch(char * string, char array, int * letter);
int main(void)
{
char * string = (char *) malloc(WordSize * sizeof(char));
//char tester = '\0';
char tester[2] = {'\0', '\0'};
int index_tester = -1; // 0 means found # index 0
/* (...) */
printf("What is the test string you wish to enter: ?\n");
fgets(string, WordSize, stdin);
if (string[WordSize-1]=='\n')
string[WordSize-1]='\0';
puts(string);
printf("Tester for the inputed string: \n");
while (getchar() != '\n') {}
///scanf("%c", &tester[0]);
fgets(tester, 2, stdin);
int ResultofSearch = stringSearch(string, tester[0], &index_tester);
if (ResultofSearch == NotFound)
{
printf("That letter is not found in the string.\n");
}
else {
printf("Character found at index %d.\n\n", index_tester);
}
return 0;
}
int stringSearch(char * string, char c, int * index)
{ ... }
It's definitely not perfect but works more less expected way.
This is for Homework
I have to write a program that asks the user to enter a string, then my program would separate the even and odd values from the entered string. Here is my program.
#include <stdio.h>
#include <string.h>
int main(void) {
char *str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s", &str);
while (&str[i] < 41) {
if (i % 2 == 0) {
odd[j++] = *str[i];
} else {
even[k++] = *str[i];
}
i++;
}
printf("The even string is:%s\n ", even);
printf("The odd string is:%s\n ", odd);
return 0;
}
When I try and compile my program I get two warnings:
For my scanf I get "format '%s' expects arguments of type char but argument has 'char * (*)[41]". I'm not sure what this means but I assume it's because of the array initialization.
On the while loop it gives me the warning that says comparison between pointer and integer. I'm not sure what that means either and I thought it was legal in C to make that comparison.
When I compile the program, I get random characters for both the even and odd string.
Any help would be appreciated!
this declaration is wrong:
char *str[41];
you're declaring 41 uninitialized strings. You want:
char str[41];
then, scanf("%40s" , str);, no & and limit the input size (safety)
then the loop (where your while (str[i]<41) is wrong, it probably ends at once since letters start at 65 (ascii code for "A"). You wanted to test i against 41 but test str[i] against \0 instead, else you get all the garbage after nul-termination char in one of odd or even strings if the string is not exactly 40 bytes long)
while (str[i]) {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
if you want to use a pointer (assignement requirement), just define str as before:
char str[41];
scan the input value on it as indicated above, then point on it:
char *p = str;
And now that you defined a pointer on a buffer, if you're required to use deference instead of index access you can do:
while (*p) { // test end of string termination
if (i % 2 == 0) { // if ((p-str) % 2 == 0) { would allow to get rid of i
odd[j++] = *p;
} else {
even[k++] = *p;
}
p++;
i++;
}
(we have to increase i for the even/odd test, or we would have to test p-str evenness)
aaaand last classical mistake (thanks to last-minute comments), even & odd aren't null terminated so the risk of getting garbage at the end when printing them, you need:
even[k] = odd[j] = '\0';
(as another answer states, check the concept of even & odd, the expected result may be the other way round)
There are multiple problems in your code:
You define an array of pointers char *str[41], not an array of char.
You should pass the array to scanf instead of its address: When passed to a function, an array decays into a pointer to its first element.
You should limit the number of characters read by scanf.
You should iterate until the end of the string, not on all elements of the array, especially with (&str[i] < 41) that compares the address of the ith element with the value 41, which is meaningless. The end of the string is the null terminator which can be tested with (str[i] != '\0').
You should read the characters from str with str[i].
You should null terminate the even and odd arrays.
Here is a modified version:
#include <stdio.h>
int main(void) {
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
if (scanf("%40s", str) != 1)
return 1;
while (str[i] != '\0') {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = even[k] = '\0';
printf("The even string is: %s\n", even);
printf("The odd string is: %s\n", odd);
return 0;
}
Note that your interpretation of even and odd characters assumes 1-based offsets, ie: the first character is an odd character. This is not consistent with the C approach where an even characters would be interpreted as having en even offset from the beginning of the string, starting at 0.
Many answers all ready point out the original code`s problems.
Below are some ideas to reduce memory usage as the 2 arrays odd[], even[] are not needed.
As the "even" characters are seen, print them out.
As the "odd" characters are seen, move them to the first part of the array.
Alternative print: If code used "%.*s", the array does not need a null character termination.
#include <stdio.h>
#include <string.h>
int main(void) {
char str[41];
printf("Enter a string (40 characters maximum): ");
fflush(stdout);
if (scanf("%40s", str) == 1) {
int i;
printf("The even string is:");
for (i = 0; str[i]; i++) {
if (i % 2 == 0) {
str[i / 2] = str[i]; // copy character to an earlier part of `str[]`
} else {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:%.*s\n ", (i + 1) / 2, str);
}
return 0;
}
or simply
printf("The even string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 != 0) {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 == 0) {
putchar(str[i]);
}
}
printf("\n");
here is your solution :)
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s" , str);
while (i < strlen(str))
{
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = '\0';
even[k] = '\0';
printf("The even string is:%s\n " , even);
printf("The odd string is:%s\n " , odd);
return 0;
}
solved the mistake in the declaration, the scanning string value, condition of the while loop and assignment of element of array. :)
I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw