Problems with simple c task - c

So after a few years of inactivity after studying at uni, I'm trying to build up my c experience with a simple string reverser.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
reverser();
return(0);
}
int reverser(){
printf("Please enter a String: ");
//return (0);
int len;
char input[10];
scanf("%s",&input);
int quit = strcmp(input,"quit");
if(quit == 0){
printf("%s\n","Program quitting");
return(0);
}
len = strlen(input);
printf("%i\n",len);
char reversed[len];
int count = 0;
while (count <= (len-1)){
//printf("%i\n",(len-count));
reversed[count] = input[(len-1)-count];
count++;
}
//printf("%s\n",input);
printf(reversed);
printf("\n");
reverser();
}
When I input "hello", you would expect "olleh" as the response, but I get "olleh:$a ca&#",
How do I just get the string input reversed and returned?
Bombalur

Add a '\0' at the end of the array. (as in, copy only chars until you reach '\0' - which is the point at array[strlen(array)], then when you're done, add a '\0' at the next character)

Strings are conventionally terminated by a zero byte. So it should be
char reversed[len+1];
And you should clear the last byte
reversed[len] = (char)0;

you forgot the \0 at the end of the string

This is because you are creating an array with size 10. When you take in some data into it (using scanf) and the array is not filled up completely, the printf from this array will give junk values in the memory. You should iterate for the length of the input by checking \n.

must have a size + 1 to string length so that you can have a \0 at the end of string that will solve your problem

The following is a (simple and minimal implementation of) string reverse program (obviously, error conditions, corner cases, blank spaces, wider character sets, etc has not been considered).
#include <stdio.h>
int strlen(char *s)
{
char *p = s;
while (*p)
p++;
return p - s;
}
char * strrev(char a[])
{
int i, j;
char temp;
for (i=0, j=strlen(a)-1 ; i<j ; i++, j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
int main()
{
char str[100];
printf("Enter string: ");
scanf("%s", str);
printf("The reverse is %s \n", strrev(str));
return 0;
}
Hope this helps!

Related

Storing a string in another variable in C

I am writing a program to check if the given string is a palindrome or not. I wrote a function to reverse the string but unable to store the reversed string in a different variable.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char stringPalindrome(char s[100], int i, int n){
char reversed = "";
for(i=n;i>=0;i--){
reversed += s[i];
}
return reversed;
}
int main(){
char s[100];
int i,n;
gets(s);
n = strlen(s)-1;
printf("%s", stringPalindrome(s,i,n));
return 0;
}
Is there a way to store a string in another variable without using pointers or malloc or calloc since I am new to this language and I have lots to learn
The goal here is not to check if a string is a palindrome but to reverse a string.
There are several problems in your code
char reversed = ""; is wrong, reversed is a char , not a char*nor aconst char *`
reversed += s[i]; does not appends s[i] as you expected
the parameter i of stringPalindrome has no sense, i must be a local variable, not a parameter
never use gets, if the input is longer than the receiving array the behavior is undefined
printf("%s", stringPalindrome(s,i,n)); as an undefined behavior because stringPalindrome returns a char rather than a string
The function stringPalindrome cannot store the reverse string in a local variable being an array of character then return that array whose has an undefined behavior. You can letting the input string unchanged :
use a static local variable in stringPalindrome, but each call of the function modifies the string made by a previous call
dynamically allocate the reverse string in the heap using malloc in stringPalindrome, in that case the caller has the responsibility to free the array when it stops to use it
also receive the array memorizing to the reversed string in parameter, as an out parameter, in hat case it is the responsibility of the caller to give an array enough long to store the result
Out of that in C the function strcat allows to concatenate strings, but in your case you want to add one char so directly assign that character rather than to use an expensive call to strcat (also supposing both strings are null terminated)
Using a global variable, the function has to take care to not write out of its static array :
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, size_t n)
{
static char reversed[100];
size_t i;
if (n > sizeof(reversed) - 1)
n = sizeof(reversed) - 1;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL)
puts(stringPalindrome(s, strlen(s) - 1));
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi#raspberrypi:/tmp $
Using dynamic allocation :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * stringPalindrome(const char * s, size_t n)
{
char * reversed = malloc(n + 1);
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
char * r = stringPalindrome(s, strlen(s) - 1);
puts(r);
free(r);
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi#raspberrypi:/tmp $
Managing the result in an output parameter :
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, char * reversed, size_t n)
{
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
char r[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
puts(stringPalindrome(s, r, strlen(s) - 1));
puts(r);
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -Wall s.c
pi#raspberrypi:/tmp $ ./a.out
azer ty
yt reza
yt reza
pi#raspberrypi:/tmp $
Well, no.
There is no string type in C. All we have are pointers to chars. And by convention the string runs from the given location up to the fist zero byte that follows. There is no way to escape that.
But in order to find out whether a string is a palindrome or not, you do not have to reverse if first. Just compare the first with the last character if they match continue with the second and second to last and so on. Until a pair does not match. If you run out of pairs to compare (when they meet in the middle) the string is a palindrome. That way you can sidestep the issue of creating a new string.
The simplest way to do this is to loop over the string and compare start and end characters. Use fgets() which allows you to set the max length of the string, gets() has no check so it should be avoided.
int palindrom()
{
char s[100];
if (fgets(s,sizeof s,stdin) != NULL)
{
int len = strlen(s);
if (s[len-1] == '\n') --len; // if string is 100 chars there is no \n
for (char* p = s, *q = s + len - 1; p >= q; ++p,--q)
{
if (*p != *q) return 0; // look until difference
}
return 1; // palindrome
}
puts("no input");
return 0;
}
first of all great that you started with programming.
There are three little points in your code:
You are using gets() which is a dangerous for buffer overflow, so I used fgets() here. Does not matter if you do not know what that means, because that is something advanced, but if you want to know more about that, let me know.
In printf() you want to print a string (%s) but your function stringPalindrome does return a char instead of an array of chars. Therefore you obtained an error. I fixed this by declaring the function to be of type const char*. Also char reversed = ""; defines an empty character, so in the for loop you are trying to append characters to an empty character and this gives you a memory error. I fixed this by using a second array of characters (r) like s and added him to the parameters of the function call.
Finally the for loop itself. This problem raised out of the second pa
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const char* stringPalindrome(char s[100], char r[100], int i, int p, int n){
for(i=0;i<p;i++){
r[i] = s[n];
n--;
}
return r;
}
int main(){
char s[100];
char r[100];
int i,n,p;
fgets(s, 100, stdin);
p = strlen(s);
n = p-1;
printf("%s", stringPalindrome(s,r,i,p,n));
return 0;
}

What is output of this program? and Why?

Want this program will be output "Digi" but why it's output "Dig)tal Bangladesh".
Can anyone explain?
#include<stdio.h>
int main(){
char str[120]="Digital Bangladesh";
int n;
n=strlen(str);
printf("%d \n",n);
str[4]="\0";
printf("%s",str);
return 0;
}
I have given basic explanation in the comments and improved your code a little (replaced "\0" with '\0' and included string.h for strlen()).
#include <stdio.h>
#include <string.h>
int main() {
char str[120] = "Digital Bangladesh";
int n = strlen(str); // can combine declaration and assignment into a single statement;
// this will assign the actual length of string str to n
printf("%d \n", n);
str[4] = '\0'; // shouldn't be "\0" since anything in double quotes will be a string and not a character
// you are assigning 5th character (4th index + 1) of str to NULL ('\0') terminator character;
// now str will have content "Digi"
printf("%s", str);
return 0;
}

Beginner C, why is a bunch of random stuff added to my string?

I have the following program that I want to read in my name (Sahand) character by character and store in a string:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[6];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
The output is this:
s
Our temp is: s
Our total string is: s
a
Our temp is: a
Our total string is: sa
h
Our temp is: h
Our total string is: sah
a
Our temp is: a
Our total string is: saha
n
Our temp is: n
Our total string is: sahan
d
Our temp is: d
Our total string is: sahandd\350\367\277_\377
Program ended with the string: sahandd\350\367\277_\377
Program ended with exit code: 0
As you can see, everything is going fine until the final letter, d, is entered, when another d and a bunch of random stuff is added onto the string. Could someone explain to me what is happening here?
You should be adding the null character to the string before printing. Since you're printing inside a loop, add it to the next character. Just absolutely be sure that the for loop doesn't go beyond the bounds of the array.
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
Another option is to actually initialize each character in the C-String to be the '\0' character (without ever overwriting the last one); As some others have mentioned in the comments, this can be accomplished in the declaration of the array as such:
char str[7] = { 0 };
You need null character('\0') to end your string(array) at the 5th index in order to tell the compiler that this is the end of string(in your case character array i.e., str). But you were using 5th index to store character 'd'.
The compiler is taking garbage value from the memory
In order to run your program correctly, you need to declare the str array as below:
char str[7];
And insert null character('\0') at (i+1)th position.Look below:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
After reading the comments, I changed the following line in my program:
char str[6];
to
char str[7];
That did the trick and the program executes as I wish.
EDIT:
In addition to changing this line, I added a str[6] = 0; after the variable declaration.

Integer from pointer warning

I have I problem. I get 2 warnings from console, but I dont know what's wrong with my code. Can you have look?
Program suppose to show lines with at least 11 characters and 4 numbers
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
if(isalpha(line)) numberAlpha++;
else if(isdigit(line)) numberDigit++;
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Both isalpha() and isdigit() takes an int, not a char *, as argument.
In your code, by passing the array name as the argument, you're essentially passing a char * (array name decays to the pointer to the first element when used as function argument), so, you're getting the warning.
You need to loop over the individual elements of line and pass them to the functions.
That said, just a suggestion, for hosted environment, int main() should be int main(void) to conform to the standard.
isalpha and isdigit are supposed to test if a char taken as int (a char can be safely converted to an int) is the encoding of an alphanumeric or digit character. You pass a char array, not an individual char. You need to test each char of the string you got, so you need a loop as:
for (int i=0; i<strlen(line); i++) {
if (isalpha(line[i])) numberAlpha++;
...
}
It is better to compute the length once:
int length = strlen(line);
for (int i=0; i<length; i++) {
...
}
You may also use a pointer to move along the string:
for (char *ptr = line; *ptr!=`\0`; ptr++) {
if (isalpha(*ptr)) ...
...
}
isalpha() and isdigit() functions take an int. But you are passing a char* i.e. the array line gets converted into a pointer to its first element (see: What is array decaying?). That's what the compiler complains about. You need to loop over line to find the number of digits and alphabets in it.
Also note that fgets() will read in the newline character if line has space. So, you need to trim it out before counting.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
line[strcspn(line, "\n")] = 0; // Remove the trailing newline, if any.
for (size_t i = 0; line[i]; i++) {
if(isalpha((unsigned char)line[i])) numberAlpha++;
else if((unsigned char)isdigit(line[i])) numberDigit++;
}
printf("alpha: %d, digits:%d \n", numberAlpha, numberDigit);
}
return 0;
}
Ok, i got something like this:
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
int i;
for(i=0; i<strlen(line); i++){
if(isalpha(line[i])) numberAlpha++;
else if(isdigit(line[i])) numberDigit++;
}
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Now the question is, if it is passible to make it first accepts data and then display only those line which follows the if statment. Now it shows line just after input it.

Would does this function which converts a char array to an int array not work?

This program is supposed to convert the array of chars (string) into an array of ints by subtracting 97 from their ascii value (the input should be lower case cause a has an ascii value of 97). So if i enter the string abcd i should get 0123 but instead I somehow get this: 012134513789. I can't figure out where the problem is.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void userEnter(int*pattern, int n);
int main(void)
{
int n, i;
printf("What is the length of the array: ");
scanf("%d",&n);
int pattern[n];
printf("Enter the char array: ");
userEnter(pattern, n);
printf("The int array is: ");
for(i=0;i<n;i++)
{
printf("%d",pattern[i]);
}
printf("\n");
}
void userEnter(int*pattern, int n)
{
char input[n];
scanf("%s", input);
int i;
for(i = 0; i < n-1; i++)
{
pattern[i] = input[i]-97;
}
}
char input[n];
scanf("%s", &input);
should be
char input[n+1];
scanf("%s", input);
input is equivalent to &input[0]
You should also exit the for loop in userEnter when you encounter the nul character that ends the user-entered string. e.g. with something like
char* p = input;
while (*p != '\0') {
*pattern = (*p) - 'a';
p++;
pattern++;
}
As KingsIndian points out, you also need to increase the size of your input buffer. At present, you overflow that buffer and overwrite the loop counter i;
The length parameter n includes one character for null as well. So, if you input length for n 4 then you can only input 3 characters, for example abc because the 4th is for the null.
So you should change the declaration accordingly:
Change:
char input[n];
to:
char input[n+1];
Note that variable length arrays are allowed only since C99.

Resources