Program to reverse a string in C without declaring a char[] - c

I need to reverse a given string and display it without using the value At[index] notation , I tried the below program using pointers,but it does not print anything for the reverse string,
Please help!
int main()
{
char* name=malloc(256);
printf("\nEnter string\n");
scanf("%s",name);
printf("\nYou entered%s",name);
int i,count;
count=0;
//find the length
while((*name)!='\0')
{
count++;
name++;
}
//pointer now at
printf("\n%p",name);
printf("\nLength is %d",count);
name=name+count;
//pointer now at
printf("\n%p",name);
for(i=0;i<(count);i++)
{
printf("%c",(*name));
name=name-1;
}
return 0;
}

Remove name=name+count; because of the name++ in the precedent loop moved name pointer to the '\0' char;
#include<stdio.h>
#include<stdlib.h>
int main()
{
char* name=malloc(256);
printf("\nEnter string\n");
scanf("%s",name);
printf("\nYou entered%s",name);
int i,count;
count=0;
//find the length and move name pointer
while((*name)!='\0')
{
count++;
name++;
}
//pointer now at
printf("\nPointer is: %p",name);
printf("\nLength is: %d\n",count);
for(i=1;i<=(count);i++)
{
printf("%c",*(name-i));
}
printf("\n");
return 0;
}
OR change the final loop to
for(i=0;i<(count);i++)
{
name--;
printf("%c",*name);
}

Remove name=name+count; and add name--;

Important: scanf(" %s", name); has no bounds checking on the input. If someone enters more than 255 characters into your program, it may give undefined behaviour.
Now, you have the char array you have the count (number of char in the array), and you make name++ (name has the last char offset) then why do you need to bother doing stuffs like this?
name=name+count;
Try this:
#include <stdio.h>
int main()
{
char* name = malloc(256);
// char name[256];
printf("\nEnter string\n");
// scanf("%s", name);
fgets(name, 254, stdin); // carriage return and null character (256-2)
printf("\nYou entered %s", name);
int i, count;
count = 0;
//find the length
while ((*name) != '\0' && (*name) != '\r') {
count++;
name++;
}
//pointer now at
// printf("\n%p", name);
// printf("\nLength is %d", count);
// name = name + count;
//pointer now at
// printf("\n%p", name);
for (i = count; i >= 0; i--) { // starts from last '\0'
printf("%c", (*name));
name = name - 1;
}
return 0;
}
I got the following output:
Enter string rakeb
You entered rakeb
bekar

The easiest way? Just replace them with their syntactic equivalent:
arr[index] // is sugar for ...
arr + index
Then, instead of using two indices to traverse just use pointers. Using this you can actually find a solution pretty easy:
void nreverse(char * str) {
char * forward = str;
char * backward = str + strlen(str) - 1;
while (forward < backward) {
char temp = *forward;
*forward = *backward;
*backward = temp;
++forward;
--backward;
}
}

Try this which will not only print but also reverse string and store it in name.
#include <stdio.h>
int main()
{
char* name = malloc(256);
char *backup1 = *bakcup2 = name;
printf("\nEnter string\n");
fgets(name, 254, stdin); // carriage return and null character (256-2)
printf("\nYou entered %s", name);
while ((*backup1) != '\0' && (*backup1) != '\r') {
backup1++;
}
backup1--; // Because here backup1 was pointing to '\0' or '\r'.
while(backup1 > backup2){
/* Swapping characters */
char temp;
temp = *backup1;
*backup1 = *backup2;
*backup2 = temp;
backup1--;
backup2++;
}
backup1 = name;
while(*backup1 != '\0' && *backup1 != '\r') {
printf("%c", (*backup1));
backup1++;
}
return 0;
}

Please post code that cleanly compiles
The current posted code is missing the required/used header files
the following code
1) includes error checking
2) limits the length of the user supplied string
to avoid a input buffer overflow
3) eliminates certain lines (commented out)
that caused 'name' to point to the wrong location
4) incorporates '\n' at the end of the printf() format strings
so the info will be printed rather than held
in the buffer for stdout
5) at the end, passes the pointer to the malloc'd memory
to the free() function
6) corrects the loop count when printing the
reverse of the input string
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN (256)
int main()
{
char* name=NULL;
char* temp = NULL;
if( NULL ==(name=malloc(256)) )
{ // then malloc failed
perror( "malloc for name[] failed");
exit( EXIT_FAILURE );
}
// implied else, malloc successful
temp = name; // save ptr to malloc'd memory
printf("\nEnter string\n");
if( 1 != scanf("%255s", name) )
{ // then scanf failed
perror( "scanf for name failed");
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("\nYou entered: %s\n",name);
int i,count;
count=0;
//find the length
while((*name)!='\0')
{
count++;
name++;
}
//pointer now at
printf("\nAddress of last char in name[]: %p\n",name);
printf("\nLength is %d\n",count);
//name=name+count;
//pointer now at
//printf("\n%p",name);
for(i=0;i<=count;i++)
{
printf("%c",(*name));
name--;
}
printf( "\n" );
free(temp);
return 0;
} // end function: main

Related

expected expression before char

I have written this program that asks the user for a name and then prints the name. Here are the steps in detail:
asks the user for the number of characters the name (i.e. sentence) will have. It includes empty spaces and the terminator character \0, then stores it;
it creates a block of memory with num_char addresses, and stores the address of the first item in ptr;
within the else section, an array of unknown size is declared, which will be used to store the name and its first address is assigned to ptr;
then the array is assigned with size num_char;
Here's the code:
#include <stdio.h>
#include <stdlib.h>
//an attempt at a program that asks for a name, stores it in an array and then prints it
int main() {
int num_char;
char *ptr;
printf("input number of characters of your name (spaces and terminator character included): ");
scanf("%d", &num_char);
ptr = char *malloc(num_char * sizeof(char)); //creates a block of mem to store the input name, with the same size, and then returns the adress of the beginning of the block to ptr
if (ptr == NULL) {
printf("allocation not possible");
} else {
ptr = char name[]; //ptr stores the adress of the first char in string
char name[num_char], //declaration of an array with num_char elements
printf("input name: ");
scanf("%s", name);
printf("input name was: %s", name);
}
return 0;
}
However I get three compilation errors which are:
"expected expression before 'char' " at ptr = char *malloc(num_char * sizeof(char) ); and ptr = char name[];
"expected declaration specifiers or '...' before string constant" at printf("input name: ");
I am a college student just beginning at C and programming in general so a detailed explanation of any error of any kind and how to fix it would be very much appreciated :)
These are syntax errors because:
ptr = char *malloc(num_char * sizeof(char)); should have been ptr = (char *)malloc(num_char * sizeof(char)); or simply ptr = malloc(num_char * sizeof(char));.
ptr = char name[]; is meaningless. You do not need to change ptr at all.
char name[num_char], is a C99 variable length array definition, but with a trailing , so the next line is expected to have another definition, hence the second error.
You must choose to either allocate memory from the heap with malloc() or define an array as a local variable.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int main() {
int num_char;
char *ptr;
printf("input number of characters of your name (spaces and terminator character included): ");
if (scanf("%d", &num_char) != 1 || num_char <= 1) {
printf("invalid input\n");
return 1;
}
/* discard the rest of the input including the newline */
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
//allocate a block of memory to store the name
ptr = malloc(num_char * sizeof(char));
if (ptr == NULL) {
printf("allocation not possible");
} else {
printf("input name: ");
if (scanf("%[^\n]", ptr) == 1)
printf("input name was: %s\n", name);
else
printf("no input was given\n");
free(ptr);
}
return 0;
}
Also note that scanf() may read more than num_char bytes if the input has more non white bytes, so it would be much safer, but non-trivial to given scanf() the information about the array size:
if (ptr != NULL) {
char format[32];
snprintf(format, sizeof format, "%%%d[^\n]", num_char - 1);
printf("input name: ");
if (scanf(format, ptr) == 1) {
printf("input name was: %s\n", name);
// should discard the rest of the line and the newline
} else {
printf("no input was given\n");
}
}
As I stated in the comments, this is a wierd set of requirements for, what I assume is an assignment, here is more or less what you should do, with comments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void clear_buffer()
{ // routine to clear standard input
int c;
while ((c = getchar()) != '\n' && c != EOF){}
if (c == EOF)
{
exit(EXIT_FAILURE);
}
}
int main()
{
int num_char;
char *ptr;
printf("input number of characters of your name (spaces and terminator character included): ");
// less than 9 + 1 null byte characters for the name not allowed
while (scanf("%d", &num_char) != 1 || num_char < 10)
{
printf("Bad input, try again: ");
clear_buffer();
}
ptr = malloc(num_char); // removed char*, you may wanted a cast,
// but even that is unneeded,
// The size of char is always 1 byte
// I still don't understand why this is asked, but well...
if (ptr == NULL)
{
perror("allocation not possible"); // perror prints the apropriate error
}
else
{
char name[num_char]; // declaration of an array with num_char elements
free(ptr); // to make ptr point to another memory location, it must be freed
ptr = name; // ptr now points to the first element of the name array
clear_buffer();
printf("What's the name ? ");
// read name with spaces from standard input
if (fgets(name, num_char, stdin))
{
name[strcspn(name, "\n")] = '\0'; // remove \n
printf("input name was: %s", ptr); // print name through ptr
}
else
{
puts("Bad input");
}
}
return EXIT_SUCCESS;
}
Pending on ambiguous interpretation...

Why is my function to reverse string in c not working?

I am writing some C Code where the user enters the desired string size and then a string which will be reversed then printed (as opposed to being printed in reverse.) I also would like to mention that I don't want to use external libraries, the whole point of this is to be able to do it manually. I used dynamic memory allocation to create a string of a size inputted by the user and called a "Reverse Array" function. Everything works fine until the function is called. My method for reversing the string followed the same principle as reversing a normal array but instead of moving integers around I moved characters around. Can you explain to me what I have done wrong?
My Code:
#include <stdio.h>
#include <stdlib.h>
int RvsArr(char *Str, int end)
{
int start = 0;
char tmp;
while (start < end)
{
tmp = Str[start];
Str[start] = Str[end];
Str[end] = tmp;
start++;
end--;
}
printf("%s", Str);
return 0;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
RvsArr(Str, ArrSz);
free(Str);
return 0;
}
You need to reverse the actual string, not the full buffer.
char *RvsArr(char* Str)
{
char *end, *wrk = Str;
char tmp;
if(wrk && *wrk)
{
end = Str + strlen(wrk) - 1;
while(wrk < end)
{
tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return Str;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf(" %i", &ArrSz);
char* Str;
Str = malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf(" %s", Str);
printf("\n`%s`\n", RvsArr(Str));
free(Str);
return 0;
}
https://godbolt.org/z/azob5s
For starters the user can enter a string the size of which can be less than the size of the dynamically allocated character array that stores the string.
So passing the size of the array does not make a sense. The size of the array is not the same as the size of the entered string.
Also this expression Str[end] access memory beyond the allocated array in the first iteration of the while loop.
And the return type int also does not make a sense.
Apart from this the function should not output anything. It is the caller of the function that will decide to output the result string or not.
Pay attention to that this call
scanf("%s", Str);
is unsafe. It would be better to use the function fgets. For example
fgets( Str, ArrSz, stdin );
In this case you will need to remove the new line character '\n' that the function can append to the entered string.
Without using standard string functions the function can be defined the following way as it is shown in the demonstrative program below.
Instead of the senseless return type int the function returns a pointer to the first character of the reversed string.
#include <stdio.h>
char * RvsArr( char *s )
{
char *last = s;
while ( *last ) ++last;
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main(void)
{
char s[] = "Hello World!";
puts( s );
puts( RvsArr( s ) );
return 0;
}
The program output is
Hello World!
!dlroW olleH
If you are allowed to use standard string functions then the function RvsArr can look the following way (provided that the header <string.h> is included)
char * RvsArr( char *s )
{
char *last = s + strlen( s );
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
Character arrays or string in c(as it is generally referred to) requires one extra byte which store null character ('\o' or 0) to indicate the end of string. You can store ArrSz - 1 character in your array and ArrSz byte stores the termination character('\o' or 0).
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
char tmp;
while(start < end)
{
tmp = Str[start];
Str[start] = Str[--end]; // pre decrement the counter to last char
Str[end] = tmp;
start++;
}
printf("%s", Str);
return 0;
}
or in other version
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
int last = end - 1;
char tmp;
while(start < last)
{
tmp = Str[start];
Str[start] = Str[last];
Str[last] = tmp;
start++;
last--;
}
printf("%s", Str);
return 0;
}
And some changes in main function are
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
Str[ArrSz] = '\0'; // Here we have no control on how many characters are read, scan is a security vulnerability becuse of this
printf("Input=%s, len=%d\n", Str, strlen(Str));
RvsArr(Str, strlen(Str));
free(Str);
return 0;
}

Confusion on Malloc behavior, why it last input is not taken?

This is a snippet of a program I am working on. I wanted to get information from the user, where the target variable cannot have predefined memory. For some reason my function does not work for the last section of the code. Any help will be appreciated.
Current Output:
Enter your name: Daniel
Hi Danie (expected as I put the limit to 5 characters)
Enter your phone number: 123456789
123456789
Enter your Note: (Here it breaks and does not print the contactNote variable.)
Here is the code:
char *getwords(int numberoftimes) {
char *words = malloc(sizeof(char));
int index = 0;
int character = EOF;
int size = 0;
int increase = 1;
int counter = 0;
char *temp;
while (character) {
character = getc(stdin);
if (numberoftimes == 0) {
if (character == '\n') {
character = 0;
}
} else if (counter == numberoftimes || character == '\n') {
character = 0;
}
if (size <= index) {
size += increase;
temp = realloc(words, size);
if (!temp) {
free(words);
words = NULL;
break;
}
words = temp;
}
words[index++] = character;
counter++;
}
return words;
}
int main() {
char *contactName, *contactNote;
long contactNumber;
printf("\nEnter your name: ");
char *getwords();
char *Name = getwords(5);
printf("\nHi %s\n", Name);
printf("\nEnter your phone number: ");
scanf("%lu", &contactNumber);
printf("\n%lu\n", contactNumber);
printf("\nEnter your Note: ");
char *getwords();
char *Note = getwords(0);
printf("\n%s\n", Note);
}
scanf() for the contact number leaves the ENTER sitting in the [keyboard] input buffer.
int main() {
char *contactName, *contactNote; // unused variables
long contactNumber;
printf("\nEnter your name: ");
char* getwords(); // unnecessary function declaration
char *Name = getwords(5);
printf("\nHi %s\n", Name);
printf("\nEnter your phone number: ");
scanf("%lu", &contactNumber); // leaves <ENTER> in buffer
printf("\n%lu\n", contactNumber);
printf("\nEnter your Note: ");
char* getwords(); // unnecessary function declaration
char *Note = getwords(0); // empty line because of previous <ENTER>
printf("\n%s\n", Note);
}
I suggest you also use getwords() for the number, then convert to long with strtol().
There are multiple problems in your code:
mixing getc() and scanf() is tricky as scanf() leaves the trailing newline pending in stdin so getc() reads this newline immediately. You should read all of your inputs with getwords().
the extra char *getwords(); declarations inside the body of main() are redundant and confusing.
getwords() is too complicated, especially for exiting the loop.
you do not always check for memory allocation error.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
char *getwords(const char *prompt, int maxlen) {
char *words = malloc(sizeof(char));
int index = 0;
int size = 0;
char *temp;
if (words == NULL)
return NULL;
printf("%s", prompt);
for (;;) {
int character = getc(stdin);
if (character == EOF || character == '\n')
break;
if (index < maxlen) {
if (index >= size) {
size += 1;
temp = realloc(words, size + 1);
if (!temp) {
free(words);
return NULL;
}
words = temp;
}
words[index++] = character;
}
}
words[index] = '\0';
return words;
}
int main() {
char *Name = getwords("\nEnter your name: ", 5);
if (!Name)
return 1;
printf("\nHi %s\n", Name);
char *contact = getwords("\nEnter your phone number: ", 20);
if (!contact)
return 1;
long contactNumber = 0;
sscanf(contact, "%lu", &contactNumber);
printf("\n%lu\n", contactNumber);
char *Note = getwords("\nEnter your Note: ", 10);
if (!Note)
return 1;
printf("\n%s\n", Note);
return 0;
}

C Program - Error Combine String Array into Program

I'm trying to write program to ask user to enter First and Last Name. Then my program will result their Full Name (combined First + Last Name) and the length of their Full Name. My Output right now does empty Full Name and 0 length. I guess my problem is at display_name functions. Here is my code so far. Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void display_name(char *fullname);
int count_char( char*x_ptr);
char * get_name(char * first_name, char * last_name);
#define MAX 80 // maximum number of array elements
int main(void)
{
char first_name[MAX];
char last_name[MAX];
char *x_ptr;
system("cls");
printf("Enter Last Name: \n" );
scanf("%s", &last_name );
printf("Enter First Name: \n" );
scanf("%s", &first_name );
x_ptr = get_name(first_name, last_name);
display_name(x_ptr);
puts("");
system("pause");
return 0;
}
char * get_name(char *first_name, char *last_name)
{
static char fullname[MAX];
char x;
x = 0;
strcpy(fullname, first_name);
strcat(fullname, " ");
strcat(fullname, last_name);
while (((fullname[x] = getchar()) != '\n') && (x < (MAX-1)))
{
x++;
}
fullname[x] = '\0';
return(fullname);
}
/* Function to print out string passed to it and display the length of fullname*/
void display_name(char *fullname)
{
char *a;
printf("Your Full name is ");
a = &fullname[0];
while (*a != '\0')
{
putchar(*a);
a++;
}
int length;
length = strlen(fullname);
printf("\nHas %d Characters", length);
length = count_char(fullname);
printf("\nHas %d Non Space Characters", length);
}
/* function to return count of non space characters*/
int count_char( char * x_ptr)
{
char *b;
unsigned int count=0;
b = x_ptr;
while (*b != '\0')
{
if (*b != ' ')
count++;
b++;
}
return
(count);
}
scanf("%s", &last_name );
Compiler complained and you ignored it. It should be scanf("%s", last_name );. Same goes with firstname. Yours had type char (*)[] and scanf expects char* which is what we gave in second case.
This part is doing nothing that you would do to achieve what you are trying to do.
while (((fullname[x] = getchar()) != '\n') && (x < (MAX-1)))
This is using getchar to get the characters from stdin and put it in the char array where you are storing the concatenated name.
Using static char array is not a good solution. The next time you try to use this function - it will overwrite the data previously written by another function. Illustration implementation of the function get_name would be
char * get_name(char *first_name, char *last_name)
{
char *fullname = malloc(strlen(first_name)+2+strlen(last_name));
if(!fullname){
perror("malloc");
exit(EXIT_FAILURE);
}
strcpy(fullname, first_name);
strcat(fullname, " ");
strcat(fullname, last_name);
return fullname;
}
Benefit of using this implementation is that - now the data that is being used is not closely coupled with the methods that call this one. So it can be reused independent of it's previous usage in another function.
Also when using the function get_name remember to free the dynamically allocated memory when you are done working with it.

C Reading user entered data

I'm trying to write a simple program that reads user entered strings into an array of pointers. The reading goes fine, however when I want to add an extra parameter to my method in order to save how many Strings I actually read, it stops working. The compiler isn't very helpfull so I decided to take my problem here.
Actual code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void read(char**, int *);
void write(char**);
int main() {
int amount = 0;
int * amount_p = &amount;
char *pt_p[1000];
read(pt_p,amount_p);
write(pt_p);
}
void read(char ** pt, int * amount) {
char stop[] = "STOP";
char* woord;
int i = 0;
printf("Enter a word: ");
scanf("%70s", woord);
pt[i] = malloc(sizeof(char)*(strlen(woord)+1));
pt[i] = strcpy(pt[i], woord);
i++;
while(strcmp(stop,pt[i-1]) != 0) {
printf("Enter a word: ");
scanf("%70s", woord);
pt[i] = malloc((strlen(woord)+1)*sizeof(char));
pt[i] = strcpy(pt[i], woord);
i++;
}
*amount = i;
}
void write(char ** pt) {
int i = 0;
char stop[] = "STOP";
while(strcmp(stop,pt[i]) != 0 ) {
printf("pt[%d]-> %s",i,pt[i]);
printf("X \n");
i++;
}
}
you need to allocate some space where you can enter the string
char* woord; is just declaring a pointer that points nowhere in particular.
instead declare it as
char woord[128];
to allocate 128 bytes on the stack for your input.
also use fgets() instead of scanf() to read strings, that way you can prevent user from entering a too large string.
if ( fgets( woord, sizeof(wooord), stdin ) != NULL )
{
char* p = strchr( woord, '\n' );
if (p != NULL )
{
*p = '\0';
}
}

Resources