here you have a working example:
#include <stdio.h> // printf
#include <stdlib.h> // malloc, free
#include <string.h> // strlen
int main() {
char* s = "hello";
size_t l = strlen(s);
char* r = (char*)malloc((l + 1) * sizeof(char));
r[l] = '\0';
int i;
for(i = 0; i < l; i++) {
r[i] = s[l - 1 - i];
}
printf("normal: %s\n", s);
printf("reverse: %s\n", r);
free(r);
}
your code was wrong in length + 1 it should say length - 1.
and you have to pay attention to the terminating '\0'.
here you have a working example:
#include <stdio.h> // printf
#include <stdlib.h> // malloc, free
#include <string.h> // strlen
int main() {
char* s = "hello";
size_t l = strlen(s);
char* r = (char*)malloc((l + 1) * sizeof(char));
r[l] = '\0';
int i;
for(i = 0; i < l; i++) {
r[i] = s[l - 1 - i];
}
printf("normal: %s\n", s);
printf("reverse: %s\n", r);
free(r);
}
your code was wrong in length + 1 it should say length - 1.
and you have to pay attention to the terminating '\0'.
The correct code is
for(j=length-1; j>=0; j--){
printf("%c", word[j]);
This is because the string's elements are indexed from 0 to length-1. For example,
word == "Hello"
length == 5
word[0] == 'H'
word[1] == 'e'
word[2] == 'l'
word[3] == 'l'
word[4] == 'o'
c - Reverse a word in the char array - Code Review Stack Exchange
Looping through user input and reversing character array in C? - Stack Overflow
Reverse a character array using recursion in C - Stack Overflow
recursion - reverse a character in array using recusion in C - Stack Overflow
Videos
Memory management
Right now, your code leaks memory--every time you call reverse, it allocates some memory, and none of your other code frees it again.
If all you're doing is reversing one string, then exiting, that's of little consequence--but if you try to use this in real code, leaking memory like this is generally unacceptable.
const correctness
Since you're not modifying the input string, you might as well use const in the function's signature:
char* reverse(char const * str);
Buffer overrun protection
Right now you have:
scanf("%s", word);
This is essentially equivalent to gets(word);. That is to say, it provides absolutely no protection against the user entering a string longer than you've provided space to store. When using %s with scanf (or cousins like fscanf, sscanf, etc.) you need to specify the maximum length:
scanf("%49s", word);
Alternatively, consider using fgets, which also requires you to specify the buffer size.
Note that there's a difference in the size you specify though. With fgets, you specify the size of the buffer, but with scanf you specify the number of characters it's allowed to read, which is one less than the size of the buffer itself. Also note that fgets normally retains the \n at the end of what was entered though (if you get data without a \n on the end, it means the buffer you supplied wasn't large enough to hold all the data that was entered).
Unnecessary Cast
When you allocate your memory:
char* reversed = (char*) malloc(sizeof(char) * strlen(str) + 1);
...you're currently casting the result of malloc. This is generally frowned upon by C programmers--it's unnecessary and it can cover up a bug of having failed to include the right header to declare/prototype malloc correctly.
char* reversed = malloc(sizeof(char) * strlen(str) + 1);
The cast is only necessary if you decide to write C that can also compile as C++. This tends to give the worst of both worlds, and should generally be avoided--if you're going to compile this as C++, use std::string and std::reverse.
Size Computation
When you allocate memory, you multiply the length by sizeof(char), but sizeof(char) is guaranteed to be 1, so the multiplication accomplishes nothing.
Even if you decide to leave the multiplication in (since it is necessary for types other than char), I prefer to use code like this:
char* reversed = malloc(sizeof(*reversed) * strlen(str) + 1);
This has the advantage that when/if you (for example) decide to support wide characters, you can change it to something like:
wchar_t* reversed = malloc(sizeof(*reversed) * (wcslen(str) + 1));
...so the argument to sizeof doesn't need to change at all (and believe me--if you decide to do something like this, you have enough headaches to deal with, so even a small help will be welcome).
Bug: off-by 1
// reversed[j + 1] = '\0';
reversed[j] = '\0';
Avoid mixing int/size_t types.
size_t and int have 1) different sign-ness and 2) potential far different positives ranges with size_t usually more than int. size_t is the right-size type for array indexing and string lengths.
"how can I optimize code" --> No need to call strlen() twice. Weak compilers will iterate the length of str on each call when only once is needed.
Check malloc() results
// Use size_t index for i, j
char* reverse_alloc(const char *str) {
size_t i = strlen(str);
char* reversed = malloc(sizeof *reversed * (i + 1));
if (reversed) {
size_t j = 0;
while (i > 0) {
i--;
reversed[j] = str[i];
j++;
}
reversed[j] = '\0';
}
return reversed;
}
To reverse in place:
char* reverse_in_place(char *str) {
size_t len = strlen(str);
size_t i = 0;
while (len > i) {
char tmp = str[--len];
str[len] = str[i];
str[i++] = tmp;
}
return str;
}
You almost got it except for two things
The indices in c go from
0toN - 1, so instead ofint i = 0; while(i <= 255) {it should be
for (int i = 0 ; i < sizeof(inputString) ; ++i) {as you can see the loop goes from
i == 0toi == 254ori < 255and noti <= 255. The same goes for the reverse loop, it should start atsizeof(inputString) - 1or254.Be careful using the
sizeofoperator.You have to pass the address to the next character.
scanf(" %c", &inputString[i]);
A better way to do this would be
int next;
next = 0;
for (int i = 0 ; ((i < sizeof(inputString) - 1) && ((next = getchar()) != EOF)) ; ++i)
inputString[i] = next;
This accepts arbitrary length input.
#include <stdio.h>
#include <stdlib.h>
typedef struct ll {
struct ll *next, *prev;
char c;
} ll_t;
ll_t *
newll() {
ll_t *rv;
if ((rv = calloc(sizeof (ll_t), 1)) != NULL)
return rv;
fprintf(stderr, "out of memory, fatal\n");
exit(-1);
}
int
main()
{
ll_t *llp = newll();
printf("Enter text to put in reverse order: ");
while((llp->c = getchar()) != EOF) {
if (llp->c == '\n')
break;
llp->next = newll();
llp->next->prev = llp;
llp = llp->next;
}
for( ; llp != NULL; llp = llp->prev)
putchar(llp->c);
putchar('\n');
}
A few observations and criticisms:
The math.h and stdlib.h header files are not needed for the posted code. While char strArray[30] is large enough to hold the input string, it is better to use empty brackets in a string initializer unless you need a specific size that is larger than the initial string. This is less error-prone, and just easier, since there is no need to count characters, and no need to remember to include space for the null-terminator. You probably want to move the puts(""); to after the call to stringReverse(), since this function does not print a newline character. It usually seems better to use putchar('\n'); for something like this; putchar() is designed to print only one character, and so is the right tool for the job.
It seems that with the statement if (strArray != "\n") {} the goal is to check if the first character is a newline, but there are a few problems with this. First, "\n" is a string, not a character; next, strArray is a pointer to the first character of the array strArray[], not the first character itself. There is no '\n' character in the input string, so even if this condition were correctly written, it would always be true, and this code would enter an infinite recursion. Finally, the argument passed to stringReverse() is never changed, so there is no way for the recursion to end. For recursion to succeed, a base case must be converged upon.
A solution is to compare the first character of the array with '\0'. If the first character is not the null-terminator, the stringReverse() function is called again, this time with the value strArray + 1. The program will continue recursively calling stringReverse() until an empty string is passed in, at which point the final call to stringReverse() returns to its caller (the previous call to stringReverse()), where the last character of the string is printed, before returning to its caller,.... Each of the stringReverse() frames is returned to, in the reversed order in which they were called, and each of these frames prints a character of the string, until finally the first frame is reached, and the first character is printed, before returning to main().
Note that in a function call, and in fact most expressions, arrays decay to pointers to their first elements. So, in stringReverse() strArray is a pointer to char that points to the first element of the array provided as an argument by the caller. Also note that in a function declaration such as void stringReverse(char strArray[]) array types are adjusted to appropriate pointer types, so this declaration is equivalent to void stringReverse(char *strArray).
#include <stdio.h>
void stringReverse(char strArray[]);
int main(void)
{
char strArray[] = "Print this string backwards.";
stringReverse(strArray);
putchar('\n');
return 0;
}
void stringReverse(char strArray[])
{
if (*strArray != '\0') {
stringReverse(strArray + 1);
putchar(*strArray);
}
}
Program output:
.sdrawkcab gnirts siht tnirP
First, you need to return an value.
Then, what your algorithm should to do? Run until the final of your string and then return variable by variable in reverse with just one parameter, well you just need pass this parameter shorter every loop.
Like this:
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
void stringReverse(char strArray[], int i) {
if (strArray[0] != NULL)
if (strArray[0] != '\0') {
int c = 0;
char str[30];
while (c < strlen(strArray)) {
str[c] = strArray[2 + c -1];
c++;
}
str[c] = '\0';
stringReverse(str);
}
printf("%c", strArray[0]);
}
int main(int argc, char *argv[]) {
char strArray[30] = "Print this string backward.";
stringReverse(strArray, 0);
printf("\n\n");
system("Pause");
return(0);
}
Your array indexes are off. When i = strlen(str) your code will look like this:
reversed[strlen(str)] = str[-1];
str[-1] is undefined. You also do not NULL terminate reserved.
The problem is in how you are indexing the array. The below code reflects the needed changes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void isPoli(char *str);
int main()
{
char name[30] = "abcde";
isPoli(name);
return 0;
}
void isPoli(char *str){
int iLen = strlen(str) - 1;
char reversed[iLen];
for(int i = 0; i<= iLen ;i++){
reversed[i] = str[ iLen - i ];
}
reversed[iLen + 1] = (char)0x0;
printf("\n%s - %s\n", reversed,str);
}
You can store each digit in an array:
} else {
char arr[32];
int counter = 0;
while (d != 0) {
int radix;
radix = d % b;
d = d / b;
char basechars[] = "0123456789ABCDEF";
arr[counter++] = basechars[radix];
}
if (counter == 0)
arr[counter++] = '0';
arr[counter++] = '\0';
print_rev(arr);
printf("\n");
}
and then print the string using a recursive function (it will reverse the output):
void print_rev(const char *s)
{
if (*s) {
print_rev(s + 1);
printf("%c", *s);
}
}
or directly:
} else {
char arr[32];
int counter = 0;
while (d != 0) {
int radix;
radix = d % b;
d = d / b;
char basechars[] = "0123456789ABCDEF";
arr[counter++] = basechars[radix];
}
if (counter == 0) {
printf("0");
else {
while (counter--)
printf("%c", arr[counter]);
}
printf("\n");
}
- Reversing the array is the most straightforward way.
- Use the limit.h macro LONG_BIT to know the maximum needed characters to store. This sizes your array.
- I'm also checking the base for the upper limit of 16.
- Build the array, then print it. Note it handles 0 just fine.
You also forgot negative numbers.
} else if (b > 16) { printf(" Your base is too high! \n"); } else { const char basechars[] = "0123456789ABCDEF"; char arr[LONG_BIT]; // d is an integer, so LONG_BIT holds // enough characters for a binary representation. int counter = 0; int negative_flag = 0; if (d < 0) { d = -d; negative_flag = 1; } do { int digit = d % b; d = d / b; arr[counter++] = basechars[digit]; } while (d != 0); if (negative_flag) { printf ("-"); } while (counter--) { printf ("%c", arr[counter]); } printf ("\n"); }
Neither your interviewer can write a code for that.
char *ch="krishna is the best";
you cant change data in readonly part of memory and ch points to a read only memory.
Update:- An Excerpt from N1548 (§6.7.9)
EXAMPLE 8
The declaration
char s[] = "abc", t[3] = "abc";
defines ‘‘plain’’ char array objects s and t whose elements are initialized with character string literals.
This declaration is identical to
char s[] = { 'a', 'b', 'c', '\0' },t[] = { 'a', 'b', 'c' };
The contents of the arrays are modifiable.
On the other hand, the declaration
char *p = "abc";
defines p with type‘‘pointer to char’’and initializes it to point to an object with type‘‘array of char’’with length 4 whose elements are initialized with a character string literal. If an attempt is made to usepto modify the contents of the array, the behavior is undefined.
You can see applying swapping on such data type is dangerous.
It is suggested to write code as:-
char ch[]="krishna is the best";
and then apply an XOR swap at every encounter of a space character.
This doesn't sound too hard, if I understand it properly. Pseudocode:
let p = ch
while *p != '\0'
while *p is whitespace
++p
let q = last word character starting from p
reverse the bytes between p and q
let p = q + 1
The reversal of a range of bytes is trivial once you have pointers to the start and end. Just loop over half the distance, and swap the bytes.
Of course, as pointed out elsewhere, I assume that the buffer in ch is actually modifiable, which requires a change in the code you showed.