Reverse char array with pointer in C - c

I want to reverse a char array using pointers, but all I get when I printf the pointer is null. I don't know what I'm doing wrong or how to fix it. So how can I reverse the string in a similar way?
#include <stdio.h>
void reverse(char *cstr);
int main()
{
char a[100];
char *p = a;
printf("geef een string "); // ask user to write a word
scanf("%s", &a);
reverse(p);
printf("%s", *p);
}
void reverse(char *p)
{
int i = 0;
char temp;
int lengte;
for(i = 0; *(p+i) != '\0'; i++)
{
lengte++; // length of char array without the '\0'
}
for(i = 0; i < lengte; i++)
{
temp = p[i]; // something goes wrong here but I don't know what
p[i] = p[lengte-i];
p[lengte-i] = tem;
}
}
Something goes wrong at the
p[i] = p[lengte-i];
p[lengte-i] = tem;
part. What do I need to change it to?

Two adjustments:
replace
printf("%s", *p);
with
printf("%s", p);
because printf is expecting a pointer, not a dereferenced pointer,
and
for(i = 0; i < lengte; i++)
with
for(i = 0; i < lengte--; i++)
because your counting of the length in the loop before that one ends up with one char too many. Hence the \0 is placed at the beginning of the string.
$ gcc test.c && ./a.out
geef een string 1234
4231$

Related

looping array of pointers to free them makes program crash in c

Full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printarray(int* array, int arraysize){
for (int i = 0; i<arraysize; i++){
printf("%d\n", *array);
array++;
}
}
void printStrArray(char** array, int arraysize){
int j = 0;
for (int i = 0; i<arraysize; i++){
j = 0;
while (array[i][j] != '\0'){
printf("%c", array[i][j]);
j++;
}
printf("\n");
}
}
int isStringInArray(char* string, char** stringArray, int arrayLen){ // returns 1 if string is contained in the array.
for (int i = 0; i < arrayLen; i++){
if (strcmp(string, stringArray[i]) == 0){
//printf("%s is equal to %s %d\n", string, stringArray[i], i);
return 1;
}
}
return 0;
}
int lenstring(char* string){ // checks string length (works only if string has null character at the end.)
char currchar = string[0];
int strlen = 0;
while (currchar != '\0'){
strlen++;
currchar = string[strlen];
}
return strlen;
}
char** riassemble(char* stringa){
char** riassembleds = calloc(1, sizeof(char*));
char* charLen = malloc(sizeof(char));
riassembleds[0] = charLen;
int riassembledLen = 1;
int stringalen = lenstring(stringa);
char tempstring[stringalen];
strcpy(tempstring, stringa);
for (int i = 0; i < stringalen; i++){
for (int j = 0; j < stringalen; j++){
tempstring[i] = stringa[j];
tempstring[j] = stringa[i];
//printf("%s\n", tempstring);
if (isStringInArray(tempstring, riassembleds, riassembledLen) == 0){
riassembleds = realloc(riassembleds, (riassembledLen+1)*sizeof(char*));
riassembledLen++;
riassembleds[riassembledLen-1] = calloc(stringalen, sizeof(char));
printf("%p\n", riassembleds[riassembledLen-1]);
strcpy(riassembleds[riassembledLen-1], tempstring);
}
strcpy(tempstring, stringa);
}
}
*charLen = (char)riassembledLen;
riassembleds[0] = charLen; /*return the array with the length of the it casted into a char pointer as the first element*/
return riassembleds;
}
int main(int argc, char *argv[]){
char** array = riassemble("ciao");
int arraylen = (int)(*(array[0]));
printf("\n%d\n", arraylen);
printStrArray(array, arraylen);
for (int i=0; i<arraylen; i++) {
free(array[i]);
}
free(array);
return 0;
}
i'm making a function that returns an array of pointers to a char, in which the first element is a pointer that points to the length of the array casted into a char.
When i try to free the elements in the array with
char** array = riassemble("ciao"); /*Creates the array*/
int arraylen = (int)(*(array[0])); /*Gets the length*/
for (int i=0; i<arraylen; i++) {
free(array[i]);
}
The program crashes after trying to free the second element of the array which is defined here:
riassembleds = realloc(riassembleds, (riassembledLen+1)*sizeof(char*));
riassembledLen++;
riassembleds[riassembledLen-1] = calloc(stringalen, sizeof(char));
printf("%p\n", riassembleds[riassembledLen-1]);
strcpy(riassembleds[riassembledLen-1], tempstring);
I really don't understand why this happens, one thing i noticed is that if i print the pointers that it's trying to free, they're not the same as when i print them right after allocating them in the riassemble function, but other than that i have no idea what i'm doing wrong.
edit: i was wrong about the fact that they're not the same, they actually are, i got confused.
Your function lenstring will return the length of the string without the terminating null character.
Therefore, the line
char tempstring[stringalen];
will create an array tempstringthat is sufficient in size to store the string stringa without the terminating null character.
However, the function call
strcpy(tempstring, stringa);
requires that tempstring is large enough to store stringa with the terminating null character. You are therefore writing to tempstring out of bounds, invoking undefined behavior.
In order to fix this, I recommend that you change the line
char tempstring[stringalen];
to:
char tempstring[stringalen+1];
The line
riassembleds[riassembledLen-1] = calloc(stringalen, sizeof(char));
has the same problem, as it only allocates sufficient space without the terminating null character, which causes the line
strcpy(riassembleds[riassembledLen-1], tempstring);
to invoke undefined behavior for the same reason.
Therefore, the line
riassembleds[riassembledLen-1] = calloc(stringalen, sizeof(char));
should be changed to
riassembleds[riassembledLen-1] = calloc(stringalen+1, sizeof(char));
I was able to find these errors very easily by using AddressSanitizer on your program.

Adding strings to 2D array in C

I'm trying to write a program that looks for the first empty space in a 2D array and adds a custom string to that space. I have tried some things that i found on the internet but none seem to work or match my specific scenario. This is it:
#include <stdio.h>
#include <string.h>
int tags[10] = {1,2,3,4,5};
char owners[10][10] = {"per1", "per2", "per3", "per4", "per5"};
int tagAdd;
char ownerAdd;
int i;
int addBool;
int j;
int len;
int main()
{
printf("Enter the tag ID you want to add: ");
scanf("%d", &tagAdd);
printf("Enter the tag owners name: ");
scanf("%d", &ownerAdd);
len = strlen(ownerAdd);
while (i<10)
{
if (tags[i] == 0)
{
tags[i] = tagAdd;
owners[i][len] = ownerAdd; //This is the part I can't figure out
addBool = 1;
}
if (addBool == 1)
{
break;
}
i++;
}
i = 0;
addBool = 0;
len = 0;
while (i<10)
{
printf("tag[%d]", tags[i]);
len = strlen(owners[i]);
printf(" is owned by ");
while (j < len)
{
printf("%c", owners[i][j]);
j++;
}
printf("\n\r");
i++;
j = 0;
}
}
You cannot do this:
char ownerAdd;
scanf("%d", &ownerAdd);
len = strlen(ownerAdd);
You are passing the incorrect types. ownerAdd is a single char, scanf
expects with %d a pointer to int, you are passing a pointer to char and if
scanf converts the value, it will overflow. And strlen expects a char*
which points to a valid string (0-terminated). You are doing all this wrong.
This would be correct:
char ownerAdd[100];
scanf("%99s", ownerAdd);
len = strlen(ownerAdd);
And for replacing a value:
owners[i][len] = ownerAdd; //This is the part I can't figure out
is also wrong, because owners[i] is a char[10], you have to do:
strncpy(owners[i], ownerAdd, sizeof owners[i]);
owners[i][sizeof(owners[i]) - 1] = 0;
to copy the string.
The next error is that you don't initialize i and do (the first loop)
while (i<10)
{
...
}
this is going to fail. Same thing with j, it is uninitialized.

Reversing a string in C using loop [duplicate]

This question already has answers here:
Function to reverse string in C
(4 answers)
Closed 6 years ago.
Beginner programmer here. I'm trying to take an input from user, reverse it and show the result. For some reason, it's printing blanks instead of the reversed string. I know that array[i] has the right information because if I use this loop on line for (int i=0; i<count; i++), it's printing the right characters. It's just not printing in reverse. What am I not getting here?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
printf("Please enter a word: ");
char *word = get_string();
int count = strlen(word);
char array[count];
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
for (int i=count-1; i==0; i--)
{
printf("%c ", array[i]);
}
printf("\n");
}
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
You go over the string and copy it, you do not reverse it.
There is also a subtle bug in-waiting in your declaration of array, since you do not leave space for the '\0' character terminator. Passing your buffer to printf as a C-string, as opposed to character by character will have undefined behavior.
So to fix those two particular errors:
char array[count + 1];
array[count] = '\0';
for (int i = 0; i< count; i++)
{
array[i] = word[count - i];
}
As a side note, it may not mean much to use a VLA for this small exercise, but for larger inputs it could very well overflow the call stack. Beware.
// the header where strlen is
#include <string.h>
/**
* \brief reverse the string pointed by str
**/
void reverseString(char* str) {
int len = strlen(str);
// the pointer for the left and right character
char* pl = str;
char* pr = str+len-1;
// iterate to the middle of the string from left and right (len>>1 == len/2)
for(int i = len>>1; i; --i, ++pl, --pr) {
// swap the left and right character
char l = *pl;
*pl = *pr;
*pr = l;
};
};
And just call the function:
int main(void) {
printf("Please enter a word: ");
char *word = get_string();
// Just call the function. Note: the memory is changed, if you want to have the original and the reversed just use a buffer and copy it with srcpy before the call
reverseString(word)
printf("%s\n", word);
};
And just change
char array[count];
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
to
// add an other byte for the null-terminating character!!!
char array[count+1];
strcpy(array, word);

Code to Reverse String not clearing up previous values

I am doing this programming problem where I have reverse string of about 30 characters for 10 test cases.
My code is this:-
#include <stdio.h>
#include <string.h>
int main () {
int t;
scanf("%d",&t);
while (t--) {
char str[30];
scanf("%s",&str);
char revStr[30];
int len = strlen(str);
int i = 0;
int j = len-1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n",revStr);
}
return 0;
}
The output gets garbled up if the input string is larger than previous string.
For example,
if last-string had 6 characters, like rocket\0 and new-string, which is fun\0 has 3 characters, the output is funket\0.
char str[30];
scanf("%s",&str);
^ don't pass address of array
Just this would work -
scanf("%29s",str);
Try this:
int t;
scanf("%d", &t);
while (t--)
{
char str[30] = { 0 };
scanf("%s", &str);
char revStr[30] = { 0 };
int len = strlen(str);
int i = 0;
int j = len - 1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n", revStr);
}
You need to make two changes
Firstly change scanf("%s",&str); to
scanf("%s",str);
Secondly, after the while loop, you are not making the last element rev string \0. Add this line before the printf statement.
revStr[i] = '\0';
This should solve your problem.

C: Garbage characters in Console output

I am learning about C pointers by creating various simple functions. I have just created a function to reverse a char array. It works, but after the output it also displays a bunch of garbage chars (see screenshot below).
Here's my code:
void reverseString();
int main()
{
reverseString();
system("PAUSE");
return 0;
}
void reverseString()
{
char string1[20], string2[20];
char *ptr1, *ptr2;
ptr1 = &string1[0];
ptr2 = &string2[0];
printf("Enter string: \n");
scanf("%s", string1);
int len1 = strlen(string1);
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
printf("%s\n", string2);
}
How can I get rid of the garbage chars? Is there something wrong with my code or did I just nto account for something or what?
You forgot to nul-terminate the new string:
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
// Add this
ptr2[i] = '\0';
When you print a char*, it will keep reading until it finds that nul character. But since you left it out, it kept going and going...

Resources