Storing a string in another variable in C - 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;
}

Related

Decimal to binary using string in c....stuck with some conceptual error

#include<stdio.h>
char bin(int);
int main()
{
setbuf(stdout,NULL);
int num;
char res[50];
printf("Enter the number: ");
scanf ("%d",&num);
res=bin(num);
printf("%s",res);
return 0;
}
char bin(int num)
{
char str[50];
int i,val;
for(i=0;num>=0;i++)
{
val=num%2;
str[i]=val;
num=num/2;
}
return str;
}
I really cant understand the error in the usage of strings... to convert the decimal to binary. Whats the conceptual error Im not following?
char is a single character, so char bin(int) will not be able to return a string (i.e. a null-terminated array of characters). And you cannot "return" an an array of characters, because C does not allow to return any array as function result. You can just pass/return pointers to the begin of such arrays.
So I'd suggest to change the interface of bin to reicieve the result buffer as parameter. Don't forget to "close" the string, i.e. to write the string termination character after the last "actual" character:
void bin(int num, char* resultBuffer) {
...
resultBuffer[i] = '\0';
}
In main, you call it then like
bin(num, res);
Returning str amounts to returning a local variable, you can't do it, what you can do is to return a pointer to a previously allocated memory block that works as an array (as an alternative to the oher answer, which is a good solution).
To do this you can declare str as a pointer, allocate memory for it and return it, making sure the variable to which the value is assigned is also a pointer, all the rest can remain the same.
There are, however, problems with the bin function.
Consider the statement:
str[i] = val;
This will not work as expected you are assigning the int result of the operation, which will be 1 or 0, you need to convert this value to the respective character.
The loop for (i = 0; num >= 0; i++) is an infinite loop because num will never be negative, unless you provide it a negative number in which case it will break in the first iteration, that is to say this code only works with positive integers. You need > instead of >=.
Finally you need to null terminate the string when the conversion is complete.
Corrected code (Online):
#include <stdio.h>
#include <stdlib.h>
char *bin(int); //return pointer
int main() {
setbuf(stdout, NULL);
int num;
char *res; //use pointer to receive string assignment
printf("Enter the number: ");
scanf("%d", &num);
res = bin(num);
printf("%s", res);
return 0;
}
char *bin(int num) {
char *str = malloc(50); // allocate memory
int i, val;
for (i = 0; num > 0; i++) { // replacing >= with >
val = num % 2;
str[i] = val + '0'; // convert to character
num = num / 2;
}
str[i] = '\0'; //null terminate the string
return str;
}
Note that you should also check for the inputed value, if it is larger than what an int variable can hold it will result in undefined behavior.

Problem with finding the length of a string using pointers in a function in c

I got a task from my college which is to find the length of a string using pointers in a function.Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define max 100
int lengthchar(char *array1[])
{
int a, x = 0;
for (a = 0; *(array1++) != '\0'; a++)
{
x++;
}
return x;
}
int main()
{
char arr1[max];
int length;
printf("Enter string\n");
gets(arr1);
length = lengthchar(arr1);
printf("Length=%d", length);
return 0;
}
But when I give input something bellow:
Enter string: av
Length=9
It shows the wrong length, what's my mistake?
This is because of the way to pass a string pointer as an argument to the function.
Just change char *array1[] to char *array1 or array1[].
Have a look at the implementation below:
int lengthchar(char array1[])
{
int a,x=0;
for(a=0;*(array1++)!='\0';a++)
{
x++;
}
return x;
}
PS: variable a can be removed by using a while loop.
In your function signature, you are telling the compiler that lenghtchar() expects a pointer to character strings, or **char in other words.
What you really want to do is to change your function from int lengthchar(char *array1[]) to int lengthchar(char array1[]) or int lengthchar(char *array1). This is a bit tricky since in C, you can address an array by using the address of its first element (aka, by using pointer to its first item).
Expert C Programming has a dedicated chapter on this topic.
Now, coming to your lengthchar() function, I would do some refactoring to eliminate the variable a and use a while loop instead. I have also included another alternative implementation that relies on pointer arithmetic (more fun to me :) )
Note also that I used fgets() instead of gets() which is considered deprecated since it does not do any bounds checking.
#include <stdio.h>
#include <stdlib.h>
#define max 100
/*
* returns the lenght of the string excluding the terminating
* NULL character
*/
int lengthchar(char *array1) {
int x = 0;
while (*array1++)
x++;
return x-1;
}
int lengthchar1(char *array1){
char *p;
for (p = array1; *p; p++)
;
return p - array1 - 1; /* -1 for \0 */
}
int main() {
char arr1[max];
int length;
printf("Enter string\n");
fgets(arr1, max, stdin);
length = lengthchar(arr1);
printf("Length=%d", length);
return 0;
}
On declaring or defining a function that shall take an array of type T as an argument, use the notation: T *array or T array[]; T may stand for any valid C data type such as char, int, float, double, etc...
As for your loop, the variable a seems to be redundant because it has no effect on any part of the program. The return value of the function lengthchar() is one more than the number of characters inputted.
Also you should avoid the function gets() because it is deemed dangerous and has been removed from the C standard; use fgets() instead.
Your code should look something like this:
#include <stdio.h>
#include <string.h>
#define max 100
int lengthchar(char *str)
{
int len = 0;
while (*str++)
{
len++;
}
return len;
}
int main()
{
char str1[max];
printf("Enter string:");
fgets(str1, max, stdin);
str1[strcspn(str1, "\n")] = 0; // remove new-line character
int length = lengthchar(str1);
printf("Length = %d\n", length);
return 0;
}

Defining size for string using a variable not working properly in for loop in C

I'm trying to reverse the string input entered by user, the problem here is in function *rev, when I use size = strlen(STR); to get the length of the string and pass it into the size of the revS[size] the program outputs some garbage value for reverse string! if I pass some value instead if size in revS[10] and run the program it works as expected. I Have checked the value of size as
printf("\nlength of string is: %d\n",size);
and it gives the correct value. I'm not getting where is it going wrong!
#include<stdio.h>
#include<string.h>
char *rev(char *);
int main()
{
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
printf("You entered string : %s\n Reversed string is: %s", string, rev(string));
}
char *rev(char *STR)
{
int size, i, j = 0;
size = strlen(STR);
printf("\nlength of string is: %d\n", size);
char revS[size];
for(i = size-1; i >= 0; i--)
{
revS[j] = STR[i];
j = j + 1;
}
revS[j] = '\0';
return (revS);
}
OUTPUT:
Enter the string to reverse: mahaveer
length of string is: 8
You entered string : mahaveer
Reversed string is: ╚²b
--------------------------------
Process exited after 28.7 seconds with return value 0
Press any key to continue . . .
The issue is that your reversed string is allocated on the stack rather than the heap. When your rev function returns, all of the variables in that scope will be garbage collected. You can use malloc() to allocate memory dynamically on the heap. Note that the caller is responsible for calling free() on the string to avoid a memory leak.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *rev(char *);
int main() {
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
char *r = rev(string);
printf("You entered string: %s\nReversed string is: %s\n", string, r);
free(r);
}
char *rev(char *str) {
int i, j;
int size = strlen(str);
char *rev = malloc(sizeof(*rev) * (size + 1));
for (i = size - 1, j = 0; i >= 0; i--, j++) {
rev[j] = str[i];
}
rev[size] = '\0';
return rev;
}
Note that this code is susceptible to buffer overflows.
You have tho major UBs here. First you allocate local storage array which is not available after the function return. The second one - the size is too small to accomodate the string plus terminating zero

How get ASCII of a string

i need to get the ascii (int and hex format) representation of a string char by char. For example if i have the string "hello", i would get for int ascii 104 101 108 108 111
and for hex 68 65 6C 6C 6F
How about:
char *str = "hello";
while (*str) {
printf("%c %u %x\n", *str, *str, *str);
str++;
}
In C, A string is just a number of chars in neighbouring memory locations. Two things to do: (1) loop over the string, character by character. (2) Output each char.
The solution for (1) depends on the string's representation (0-terminated or with explicit length?). For 0-terminated strings, use
char *c = "a string";
for (char *i = c; *i; ++i) {
// do something with *i
}
Given an explicit length, use
for (int i = 0; i < length; ++i) {
// do something with c[i]
}
The solution for (2) obviously depends on what you are trying to achieve. To simply output the values, follow cnicutar's answer and use printf. To get a (0-terminated) string containing the representation,
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* convert a 0-terminated string to a 0-terminated string of its ascii values,
* seperated by spaces. The user is responsible to free() the result.
*/
char *to_ascii(const char *inputstring) {
// allocate the maximum needed to store the ascii represention:
char *output = malloc(sizeof(char) * (strlen(inputstring) * 4 + 1));
char *output_end = output;
if (!output) // allocation failed! omg!
exit(EXIT_FAILURE);
*output_end = '\0';
for (; *inputstring; ++inputstring) {
output_end += sprintf(output_end, "%u ", *inputstring);
//assert(output_end == '\0');
}
return output;
}
If you need to output an explicit-length string, use strlen() or the difference (size_t)(output_end-output).
int main()
{
enum type {decimal, hexa};
char *str = "hello";
char *temp_str = NULL;
temp_str = str;
static enum type index = decimal;
while (*str) {
if(index == decimal)
printf("%u\t", *str);
else
printf("%x\t",*str);
str++;
}
printf("\n");
if(index != hexa)
{
index = hexa;
str = temp_str;
main();
}
}
hope this will work fine as what u want, and if u want to store it in a uint8_t array, have to just declare an variable for it.
I know this is 5 years old but my first real program converted strings to ASCII and it was done in a clean and simple way by assigning a variable to getchar() and then calling it in printf() as an integer, all while it's in a loop of course, otherwise getchar() only accepts single characters.
#include <stdio.h>
int main()
{
int i = 0;
while((i = getchar()) != EOF)
printf("%d ", i);
return 0;
}
and here's the original version using the for() loop instead because I wanted to see just how small I could make the program.
#include <stdio.h>
int main()
{
for(int i = 0; (i = getchar()) != EOF; printf("%d ", i);
}
/* Receives a string and returns an unsigned integer
equivalent to its ASCII values summed up */
unsigned int str2int(unsigned char *str){
int str_len = strlen(str);
unsigned int str_int = 0;
int counter = 0;
while(counter <= str_len){
str_int+= str[counter];
printf("Acumulator:%d\n", str_int);
counter++;
}
return str_int;
}

Problems with simple c task

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!

Resources