I am rather new to the C language right now and I am trying some practice on my own to help me understand how C works. The only other language I know proficiently is Java. Here is my code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char * reverse(char word[]);
const char * reverse(char word[]) {
char reverse[sizeof(word)];
int i, j;
for (i = sizeof(word - 1); i <= 0; i--) {
for (j = 0; j > sizeof(word - 1); j++) {
reverse[i] = word[j];
}
}
return reverse;
}
int main() {
char word[100];
printf("Enter a word: ");
scanf("%s", word);
printf("%s backwards is %s\n", word, reverse(word));
return 0;
}
When the user enters a word, the program successfully prints it out when i store it but when i call the reverse function I made it doesnt return anything. It says on my editor the address of the memory stack is being returned instead and not the string of the array I am trying to create the reverse of in my function. Can anyone offer an explanation please :(
sizeof(word) is incorrect. When the word array is passed to a function, it is passed as a pointer to the first char, so you are taking the size of the pointer (presumably 4 or 8, on 32- or 64-bit machines). Confirm by printing out the size. You need to use strlen to get the length of a string.
There are other problems with the code. For instance, you shouldn't need a nested loop to reverse a string. And sizeof(word-1) is even worse than sizeof(word). And a loop that does i-- but compares i<=0 is doomed: i will just keep getting more negative.
There are multiple problems with your reverse function. C is very different from Java. It is a lot simpler and has less features.
Sizes of arrays and strings don't propagate through parameters like you think. Your sizeof will return wrong values.
reverse is an identifier that is used twice (as function name and local variable).
You cannot return variables that are allocated on stack, because this part of stack might be destroyed after the function call returns.
You don't need two nested loops to reverse a string and the logic is also wrong.
What you probably look for is the function strlen that is available in header string.h. It will tell you the length of a string. If you want to solve it your way, you will need to know how to allocate memory for a string (and how to free it).
If you want a function that reverses strings, you can operate directly on the parameter word. It is already allocated outside the reverse function, so it will not vanish.
If you just want to output the string backwards without really reversing it, you can also output char after char from the end of the string to start by iterating from strlen(word) - 1 to 0.
Edit: Changed my reverse() function to avoid pointer arithmetic and to allow reuse of word.
Don't return const values from a function; the return value cannot be assigned to, so const doesn't make sense. Caveat: due to differences between the C and C++ type system, you should return strings as const char * if you want the code to also compile as C++.
Arrays passed as params always "decay" to a pointer.
You can't return a function-local variable, unless you allocate it on the heap using malloc(). So we need to create it in main() and pass it as a param.
Since the args are pointers, with no size info, we need to tell the function the size of the array/string: sizeof won't work.
To be a valid C string, a pointer to or array of char must end with the string termination character \0.
Must put maximum length in scanf format specifier (%99s instead of plain %s — leave one space for the string termination character \0), otherwise vulnerable to buffer overflow.
#include <stdio.h> // size_t, scanf(), printf()
#include <string.h> // strlen()
// 1. // 2. // 3. // 4.
char *reverse(char *word, char *reversed_word, size_t size);
char *reverse(char *word, char *reversed_word, size_t size)
{
size_t index = 0;
reversed_word[size] = '\0'; // 5.
while (size-- > index) {
const char temp = word[index];
reversed_word[index++] = word[size];
reversed_word[size] = temp;
}
return reversed_word;
}
int main() {
char word[100];
size_t size = 0;
printf("Enter a word: ");
scanf("%99s", word); // 6.
size = strlen(word);
printf("%s backwards is %s\n", word, reverse(word, word, size));
return 0;
}
Related
#include<stdio.h>
const char *encrypt(char *str);
const char *decrypt(char *str1);
int main()
{
char str[100],str1[100];
//Encryption
printf("Enter String for encryption\n");
gets(str);
encrypt(str);
printf("%s after encryption is %s\n",str,encrypt(str));
//Encryption
printf("Enter String for decryption\n");
gets(str1);
decrypt(str1);
printf("%s after decryption is %s",str1,decrypt(str1));
return 0;
}
const char *encrypt(char *str)
{
char en[100];
int i=0;
for(;i<100;i++)
{
en[i]=str[i]+1;
}
en[i]='\0';
return en;
}
const char *decrypt(char *str1)
{
char de[100];
int i=0;
for(;i<100;i++)
{
de[i]=str1[i]-3;
}
de[i]='\0';
return de;
}
You are returning a pointer to automatic variables en and de which are stored in the stack. This in turn means after returning from the functions encrypt and decrypt their place in the memory can be used by any other variable.
so to correct that, you need to define en and de as static.
const char *encrypt(char *str){
static char en[100];
int i=0;
for(;i<100;i++){
en[i]=str[i]+1;
}
en[i]='\0';
return en;
}
const char *decrypt(char *str1){
static char de[100];
int i=0;
for(;i<100;i++){
de[i]=str1[i]-3;
}
de[i]='\0';
return de;
}
Though a more suitable and safer way to implement that would be:
#include<stdio.h>
void encrypt(char *str, char *encStr);
void decrypt(char *str1, char* decStr);
int main()
{
char str[100], encDecStr[100];
//Encryption
printf("Enter String for encryption\n");
scanf("%s", str);
encrypt(str, encDecStr);
printf("%s after encryption is %s\n",str,encDecStr);
//Decryption
printf("Enter String for decryption\n");
scanf("%s", str);
decrypt(str, encDecStr);
printf("%s after decryption is %s",str,encDecStr);
return 0;
}
void encrypt(char *str, char *encStr)
{
for(char *c = str; *c != '\0'; c++)
{
*encStr++ = *c + 1;
}
*encStr='\0';
}
void decrypt(char *str1, char* decStr)
{
for(char *c = str1; *c != '\0'; c++)
{
*decStr++ = *c - 1;
}
*decStr++='\0';
}
Note: The code was not fully tested for different use cases.
There are quite a number of errors in your code:
Returning arrays with local storage duration:
The array's life time ends (i.e. it ceases to exist) as soon as you exit from the function, thus the pointer returned is dangling, reading from it is undefined behaviour
You write beyond the bounds of your local array: en[i] = '\0' with i being 100 after the loop is out of the range of valid indices from 0 to 99, which again is undefined behaviour.
You have differing offsets for encrypting (1) and decrypting (3).
Simply adding an offset without further checks (or modulo operations) will produce different character sets for input and output strings (might be your least problem...).
You always en-/decode the entire array, which is more than actually needed. Additionally the terminating null character then is encoded as well, resulting in different lengths of input and output and garbage at the end of encoded string.
Use of gets is dangerous as it allows a user to write beyond the input array, resulting in undefined behaviour. This is the reason why it actually has been removed from C language with C11 standard – which introduces a safe alternative gets_s. Yet another alternative (especially for pre-C11 code) is fgets.
For the dangling pointer problem there are several options:
Making the array static (as mentioned already):The disadvantage of this approach is that the function is not thread-safe any more. Additionally calling the function more than once overwrites previous results, if you haven't evaluated already or copied them they are lost.
Returning a dynamically allocated array, see malloc function. This comes with the risk of the caller forgetting to free the allocated memory again, which would result in a memory leak
Changing the input array in place: Disadvantage of is having to copy the input into a backup if it is yet needed afterwards.
Letting the caller provide the buffer.
Last option is most flexible and most idiomatic one, so I'll concentrate on this one:
void caesar(char const* input, char* output, int offset)
{
int const NumChars = 'z' - 'a';
offset = offset % NumChars + NumChars;
// ^ assures valid range, can still be negative
// ^ assures positive value, possibly
// out of range, but will be fixed later
for(;*input; ++input, ++output)
{
int c = *input - 'a';
// distance from character a
c = (c + offset) % NumChars;
// ^ fixes too large offset
*output = 'a' + c;
}
// as now iterating *until* null character found we now *need*
// to add it (in contrast to original version with whole array!)
*output = 0;
}
This variant includes an interesting idea: Let the caller define the offset to be applied! The modulo operation assures the valid range of the character, no matter how large the offset is. The great thing about: If a user encoded with some number n, exactly the same function can be used to decode again with -n (which is why I simply named it caesar according to the algorithm it implements). Note that this is untested code; if you find a bug please fix yourself...
Be aware, though, that this code still has two weaknesses:
It assumes ASCII encoding or compatible – at least one where letters a to z are in contiguous range, a is first character, z is last one. This is not true for all encodings, though, consider the (in-?)famous EBCDIC.
It assumes all input is in range of Latin minuscules only (from a - z), it does not consider white-space, digits, capital letters, punctuation marks... You might want to include special handling for all of these or at least the ones you might use.
You could fix these e.g. (many other variants are thinkable as well) by
converting all characters to either upper or lower case (toupper((unsigned char)*input) – assuming case doesn't matter)
search in an array of valid characters ("ABC...XYZ012...89") for the appropriate index and if found encode like above with NumChars being array length, otherwise (whitespace, punctuation) just leave as is.
In any case, the function would then be called like:
char input[128]; // prefer powers of 2 for array lengths...
char en[sizeof(input)];
char de[sizeof(input)];
gets_s(input, sizeof(input));
caesar(input, en, 7);
// en contains encrypted string, could e.g. be printed now
caesar(en, de, -7);
// de contains decrypted string
// you could even encode/decode in place:
caesar(input, input, 7);
// just be aware that this will fail, though, for the case if input
// and output overlap and input starts before output, as then at
// some point already encoded values will be read as input again:
// caesar(input, input + 1, 7) fails!!!
There's some issues in your code :
Not a very big issue for a beginner , but you should avoid gets function.
Because it doesn't check the input , it can cause buffers overflow and various security problems , try using fgets instead.
In encrypt , and decrypt functions , you are returning the address of an array located in the stack of the function , look :
const char *encrypt(char *str){
char en[100];
int i=0;
for(;i<100;i++){
en[i]=str[i]+1;
}
en[i]='\0';
return en;
}
Here , Since the en array is declared inside the function , after the return you may get garbage string when trying to read it.
The solution here , is to either malloc it , or declare a static array outside the function , and initialize it.
You are encrypting by adding 1 to the value of the string , and decrypt it by retrieving 3 . I don't know if this is what you intended to do.
Here's a new version of your code , try to check if it suits your need :
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
static char de[100] , en[100] ;
const char *decrypt(char *str1){
memset(de , 0 , 100) ;
int i=0;
for(;i<strlen(str1);i++){
de[i]=str1[i]-1;
}
de[i]='\0';
return (const char*) de;
}
const char* encrypt(char* str){
memset(en , 0 , 100) ;
int i=0;
for(;i<strlen(str);i++){
en[i]=str[i]+1;
}
en[i]='\0';
return (const char*) en;
}
int main(){
char str[100],str1[100];
//Encryption
printf("Enter String for encryption\n");
gets(str);
encrypt(str);
printf("%s after encryption is %s\n",str,encrypt(str));
//Encryption
printf("Enter String for decryption\n");
gets(str1);
decrypt(str1);
printf("%s after decryption is %s",str1,decrypt(str1));
return 0;
}
Your code does not handle a special case for the character 'z'. Thus
en[i]=str[i]+1;
Causes the character '{' to be written to the array en instead. For learning more about why this happens, I recommend you look at ASCII tables and looking at the integer values for alphabets.
Secondly, did you mean to type -3 in there?
de[i]=str1[i]-3;
This won't work if you're planning on using the decrypt() function to decrypt strings that you made using encrypt() because you're adding 1 to the character while encrypting and then subtracting a different number when decrypting, so the result will appear garbled.
I rewrote your code for you, since this is a beginner program, I made as little changes as possible so you can understand it. I WOULD HIGHLY RECOMMEND NOT USING gets() though... See here.
#include<stdio.h>
const char *encrypt(char *str);
const char *decrypt(char *str1);
int main()
{
char str[100],str1[100];
//Encryption
printf("Enter String for encryption\n");
gets(str); // DON'T USE GETS!!! USE fgets(str, 100, stdin);
encrypt(str);
printf("%s after encryption is %s\n", str, encrypt(str));
//Encryption
printf("Enter String for decryption\n");
gets(str1); // DON'T USE GETS!!! USE fgets(str, 100, stdin);
decrypt(str1);
printf("%s after decryption is %s", str1, decrypt(str1));
return 0;
}
const char *encrypt(char *str)
{
char en[100];
int i=0;
for(; i<100; i++)
{
if (str[i] == 'z')
{
en[i] = 'a';
continue;
}
en[i] = str[i] + 1;
}
en[i] = '\0';
return en;
}
const char *decrypt(char *str1)
{
char de[100];
int i=0;
for(; i<100; i++)
{
if (str[i] == 'a')
{
en[i] = 'z';
continue;
}
de[i] = str1[i] - 1;
}
de[i] = '\0';
return de;
}
Some criticisms
Like I said, gets() is really bad... See here for more details. Although it might be too complicated for you... A better alternative is fgets!
fgets(str, num, stdin)
takes user input from the console, and then stores it inside the array str, which must be large enough to store at least num characters. Don't worry about stdin if you don't know what that means. But be sure to always write it when using fgets as an alternative to gets
Like others have already posted, albeit using more technical jargon, it's a bad idea to declare an array inside a function and then return that array. You know the function ends when the return statement is hit, and at that point all the variables that were declared inside the function will get destroyed.
That doesn't necessarily mean that you can't read the data that was in them, but it becomes a probabilistic game where there's a teeny-tiny chance that the array will get corrupted after the function exits and before the data in that array is read. This is technically Undefined Behaviour.
I hope you know about pointers. You can modify the array which you passed as a parameter directly and then return that array, thus avoiding accessing an array outside it's lifetime.
I know this code is quite simple; but that message won't stop appearing, can you help me find where the error is?
#include <stdio.h>
void Reverse(char * word[]) {
char temp = word[0];
for (int i = sizeof(word); i >= 0; i--){
for (int j = 0; j<= sizeof(word); j ++){
word[0] = word[i];
}
}
word[sizeof(word)] = temp;
printf("%s", word);
}
void main() {
Reverse(gets(stdin));
return 0;
}
gets returns char*. In this context - It is wrong to write char *[] in the function definition where you are supposedly passing a char array where input characters are being stored using gets. Also char *gets(char *str) - you need to pass a buffer to the gets where the inputted letters will be stored. You didn't pass one.
sizeof doesn't work here. It returns the size of a pointer (char*). You will have to use strlen() to get the length of the string inputted by gets.
More importantly - don't use gets - it's time to use something much safer than gets, namely fgets etc. Buffer overflow is not something you want to deal with.
Suppose you are passing an array of char* to the function reverse. Then the parameter would be char*[] which means nothing other than char** here. Here you will simply pass the char array which you will be using as buffer to gets.
I have an assignment I've been working on for a few hours now, and I can't seem to get it quite right. The assignment is to take a random number of names (from stdin), sort them, and then output them in alphabetical order. I can't find any sites online that handle this kind of sorting specifically, and have had no luck trying to implement qsort() into my code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int stringcmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}
void main(int argc, char *argv[])
{
char *input[] = {" "};
char temp[20][20];
int i = 0;
int num = 0;
int place = 0;
int stringlen = sizeof(temp) / sizeof(char);
printf("How many names would you like to enter? ");
scanf("%d", &num);
while (place < num)
{
printf("Please input a name(first only): ");
scanf("%s", input[place]);
printf("The name you entered is: ");
printf("%s\n", input[place]);
place++;
}
//qsort(temp, stringlen, sizeof(char *), stringcmp); <-- just an idea I was messing with
qsort(input, stringlen, sizeof(char *), stringcmp);
printf("Names:\n");
for(i=0; i<place; i++)
printf("%s\n", input[i]);
system("PAUSE");
return(EXIT_SUCCESS);
}
The main problem is, when I go to output my code, I cannot use the char *input variable because of how its declared. The temp[] will display, but will not be sorted by qsort because it is not declared as a pointer. Any ideas?
You can't declare your input array like that. Since you know how many the user requires, you can dynamically allocate the array:
char **input = malloc(num * sizeof(char*));
Likewise, when you read your strings in, they need somewhere to go. Simply passing an uninitialized pointer to scanf is not okay. I suggest you define the maximum length of a name and have a temporary buffer for reading it:
const size_t MAX_NAME = 50;
char name[MAX_NAME];
...
for( i = 0; i < num; i++ )
{
printf("Please input a name(first only): ");
scanf("%s", name);
input[i] = strdup(name);
}
[Note this does not prevent the user from overflowing the 'name' buffer. I used scanf for illustrative purposes only]
You seem to be passing the wrong array length to qsort. Try this:
qsort(input, num, sizeof(char *), stringcmp);
When you are finished, you need to release memory for all the names and the array.
for( i = 0; i < num; i++ ) free(input[i]);
free(input);
could you explain
the ** declarations throughout the code? I'm not sure what they're
used for, although I know the function for stringcmp is a widely used
algorithm, I have no idea how it works; I'm thrown off by the double
de-reference markers.
Yep, in the case where I used it, I am telling C that to get a single character, I have to dereference a pointer twice. When you index a pointer, it's dereferencing. So I allocated an array by requesting a block of memory containing num * sizeof(char*) bytes. Because I assigned that pointer to a char**, the compiler knows that I am pointing to a chunk of memory that contains char* values.
If I ask for input[0] (this is the same as *input) it should look at the very start of that memory and pull out enough bytes to form a char*. When I ask for input[1], it skips past those bytes and pulls out the next bunch of bytes that form a char*. Etc... Likewise, when I index a char*, I am pulling out single characters.
In your stringcmp function, you have the following situation. You passed a void* pointer to qsort so it doesn't actually know the size of the data values stored in your array. That's why you have to pass both the array length AND the size of a single element. So qsort just blindly rips through this arbitrary-length array of arbitrary-sized values and fires off memory addresses that ought to contain your data for comparison. Because qsort doesn't know anything else about your array elements except where they are located, it just uses void*.
But YOU know that those pointers are going to be the memory addresses of two of your array elements, and that your array elements are char*. So you need the address of a char* (hence you cast the pointers to char**). Now you need to dereference these pointers when you call strcmp() because that function requires a char* (ie a value that points directly to the memory containing your string characters). That is why you use the * in strcmp(*ia, *ib).
One quick way to fix your program is to declare input as an array of pointers, like this:
char *input[20];
When you read names in, use tmp[place] for your buffer, and store the pointer into input, like this:
scanf("%19s", tmp[place]);
input[place] = tmp[place];
Now sorting the input should work fine.
This has a limitation of being limited to 20 lines of 20 characters max. If you learned about malloc in the class, you should be able to fix that by allocating your strings and the string array dynamically.
I need a working code for a function that will return a random string with a random length.
What I want to do would be better described by the following code.
char *getRandomString()
{
char word[random-length];
// ...instructions that will fill word with random characters.
return word;
}
void main()
{
char *string = getRandomString();
printf("Random string is: %s\n", string);
}
For this, I am strictly forbidden to use any other include than stdio.h.
Edit: This project will be adapted to be compiled for a PIC Microcontroller, hence I cannot use malloc() or such stuff.
The reason why I use stdio.h here, is for me to be able to inspect the output using GCC.
Currently, this code gives this error.-
“warning: function returns address of local variable [enabled by default]”
Then, I thought this could work.-
char *getRandomString(char *string)
{
char word[random-length];
// ...instructions that will fill word with random characters.
string = word;
return string;
}
void main()
{
char *string = getRandomString(string);
printf("Random string is: %s\n", string);
}
But it only prints a bunch of nonsense characters.
There are three common ways to do this.
Have the caller pass in a pointer to (the first element of) an array into which the data is to be stored, along with a length parameter. If the string to be returned is bigger than the passed-in length, it's an error; you need to decide how to deal with it. (You could truncate the result, or you could return a null pointer. Either way, the caller has to be able to deal with it.)
Return a pointer to a newly allocated object, making it the caller's responsibility to call free when done. Probably return a null pointer if malloc() fails (this is always a possibility, and you should always check for it). Since malloc and free are declared in <stdlib.h> this doesn't meet your (artificial) requirements.
Return a pointer to (the first element of) a static array. This avoids the error of returning a pointer to a locally allocated object, but it has its own drawbacks. It means that later calls will clobber the original result, and it imposes a fixed maximum size.
None if these is an ideal solution.
It points to nonsense characters because you are returning local address. char word[random-length]; is defined local to char *getRandomString(char *string)
Dynamically allocate the string with malloc, populate string, and return the returned address by malloc. This returned address is allocated from the heap and will be allocated until you do not manually free it (or the program does not terminate).
char *getRandomString(void)
{
char *word;
word = malloc (sizeof (random_length));
// ...instructions that will fill word with random characters.
return word;
}
After you have done with the allocated string, remember to free the string.
Or another thing can be done, if you cannot use malloc which is define the local string in the getRandomString as static which makes the statically declared array's lifetime as long as the program runs.
char *getRandomString(void)
{
static char word[LENGTH];
// ...instructions that will fill word with random characters.
return word;
}
Or simply make the char word[128]; global.
As I understand, malloc is not an option.
Write a couple of functions to a) get a random integer (strings length), and b)a random char.
Then use those to build your random string.
For example:
//pseudocode
static char random_string[MAX_STRING_LEN];
char *getRandomString()
{
unsigned int r = random_number();
for (i=0;i<r;i++){
random_string[i] = random_char();
}
random_string[r-1] = '\0';
}
If you are not allowed to use malloc you'll have to declare an array that can be the maximum possible size at file scope and fill it with random characters.
#define MAX_RANDOM_STRING_LENGTH 1024
char RandomStringArray[MAX_RANDOM_STRING_LENGTH];
char *getRandomString(size_t length)
{
if( length > ( MAX_RANDOM_STRING_LENGTH - 1 ) ) {
return NULL; //or handle this condition some other way
} else {
// fill 'length' bytes in RandomStringArray with random characters.
RandomStringArray[length] = '\0';
return &RandomStringArray[0];
}
}
int main()
{
char *string = getRandomString(100);
printf("Random string is: %s\n", string);
return 0;
}
Both of your examples are returning pointers to local variables - that's generally a no-no. You won't be able to create memory for your caller to use without malloc(), which isn't defined in stdio.h, so I guess your only option is to make word static or global, unless you can declare it in main() and pass the pointer to your random string function to be filled in. How are you generating random numbers with only the functions in stdio.h?
An array of pointers to strings is provided as the input. The task is to reverse each string stored in the input array of pointers. I've made a function called reverseString() which reverses the string passed to it. This functions works correctly as far as i know.
The strings stored/referenced in the input array of pointers are sent one by one to the reverseString() function. But the code hangs at some point in the reverseString() function when the values of the passed string are swapped using a temp variable. I can't figure out why the code is hanging while swapping values. Please help me with this.
The code is as follows:
#include <stdio.h>
void reverseString(char*);
int main()
{ char *s[] = {"abcde", "12345", "65gb"};
int i=0;
for(i=0; i< (sizeof(s)/sizeof(s[0]) ); i++ )
{ reverseString(s[i]);
printf("\n%s\n", s[i]);
}
getch();
return 0;
}//end main
void reverseString(char *x)
{ int len = strlen(x)-1;
int i=0;
char temp;
while(i <= len-i)
{ temp = x[i];
x[i] = x[len-i];
x[len-i] = temp;
i++;
}
}//end reverseString
You are trying to change string literals.
String literals are usually not modifiable, and really should be declared as const.
const char *s[] = {"abcde", "12345", "65gb"};
/* pointers to string literals */
If you want to make an array of modifiable strings, try this:
char s[][24] = {"abcde", "12345", "65gb"};
/* non-readonly array initialized from string literals */
The compiler will automatically determine you need 3 strings, but it can't determine how long each needs to be. I've made them 24 bytes long.
The strings ("abcde" etc) could be stored in readonly memory. Anything is possible when you try to modify those strings, therefore. The pointers to the strings are modifiable; it is just the strings themselves that are not.
You should include <string.h> to obtain the declaration of strlen(3), and another header to obtain the function getch() - it is not in <stdio.h> on my MacOS X system (so I deleted the call; it is probably declared in either <stdio.h> or <conio.h> on Windows).
Hope this helps you! what i am doing here is that i am going to the address of the last character in the string then printing them all by decreasing the pointer by 1 unit (for character its 2 bytes(please check)).
//program to reverse the strings in an array of pointers
#include<stdio.h>
#include<string.h>
int main()
{
char *str[] = {
"to err is human....",
"But to really mess things up...",
"One needs to know C!!"
};
int i=0; //for different strings
char *p; //declaring a pointer whose value i will be setting to the last character in
//the respective string
while(i<3)
{
p=str[i]+strlen(str[i])-1;
while(*p!='\0')
{
printf("%c",*p);
p--;
}
printf("\n");
i++;
}
}