Printing a reversed string/array in C - c

I'm trying to print a reversed string/array. I've used the following code and it seems to be able to give my second array, revString, values in the correct order from the first array string. I am also able to print individual characters in both arrays, and I'm able to print the entire string of the first array. However the revString array doesn't print at all. I'm wondering if I am missing a huge point here.
void reverseString(char string[]) {
int i = strlen(string);
int i_2 = 0;
revString arrayet
char revString[i + 1];
char *character;
while (i > -1) {
character = &string[i];
revString[i_2] = *character;
printf("%c", revString[i_2]);
i = i - 1;
i_2 = i_2 + 1;
}
revString[i_2] = '\0';
printf("%d\n", i_2);
printf("%s", revString);
}
The code gives now the following output with example string "Hello World";
dlrow olleH13
As you can see the final printf statement doesn't do anything

In C language indexing is 0 based. so, if you make a string of 10 length, the last character will be at index 9.
In your code, when you are assigning characters to revString, your code is trying to access string[len].
your code should be like this..
int i = strlen(string) - 1;

Your code reverses the string string including the null terminator at string[i]. The resulting array starts with a null terminator, hence printf outputs nothing.
Here is a modified version:
void reverseString(char string[]) {
int i = strlen(string);
int i_2 = 0;
char revString[i + 1];
char character;
while (i > 0) {
i = i - 1;
character = string[i];
revString[i_2] = character;
//printf("%c", revString[i_2]);
i_2 = i_2 + 1;
}
revString[i_2] = '\0';
printf("%d\n", i_2);
printf("%s", revString);
}
Output:
11
dlrow olleH

Related

How to get the length of this array without strlen(), sizeof(arr) / sizeof(arr[0]); does not work, C language

This program, tokenizes a user input string, removes extra spaces and saves each word into a 2D array and then print the tokens
EXAMPLE:
input: " Hello world string house and car"
output and EXPECTED output:
token[0]: Hello
token[1]: world
token[2]: string
token[3]: house
token[4]: and
token[5]: car
THE PROBLEM:
the problem is that I achieved this by using strlen() function when printing the tokens(code located at the very bottom), I am not supposed to use any other library than stdio.h and stdlib.h, since strlen() function is defined in string.h i tried to use sizeof(arr) / sizeof(arr[0]); but it does not work as I want, the result using sizeof is :
token[0]: Hello
token[1]: world
token[2]: string
token[3]: house
token[4]: and
token[5]: car
�oken[6]: ��
token[7]: �
token[8]: ����
token[9]: �
token[10]:
I WOULD LIKE TO HAVE THE EXPECTED OUTPUT WITHOUT USING STRLEN()
#include<stdio.h>
#include <stdlib.h>
#define TRUE 1
char tokenize(char *str, char array[10][20])
{
int n = 0, i, j = 0;
for(i = 0; TRUE; i++)//infinite loop until is the end of the string '\0'
{
if(str[i] != ' '){
//position 1, char 1
array[n][j++] = str[i];// if, it is not space, we save the character
}
else{
array[n][j++] = '\0';//end of the first word
n++;// position for next new word
j=0;// start writting char at position 0
}
if(str[i] == '\0')
break;
}
return 0;
}
//removes extra spaces
char* find_word_start(char* str){
/*also removes all extra spaces*/
char *result = (char*) malloc(sizeof(char) *1000);
int c = 0, d = 0;
// no space at beginning
while(str[c] ==' ') {
c++;
}
while(str[c] != '\0'){ // till end of sentence
result[d++] = str[c++]; //take non-space characters
if(str[c]==' ') { // take one space between words
result[d++] = str[c++];
}
while(str[c]==' ') { //
c++;
}
}
result[d-1] = '\0';
//print or return char?
return result;
free(result);
}
int main()
{
char str[]=" Hello world string dudes and dudas ";
//words, and chars in each word
char arr[10][20];
//call the method to tokenize the string
tokenize(find_word_start(str),arr);
int row = sizeof(arr) / sizeof(arr[0]);
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
for(int i = 0;i <= strlen(arr);i++)
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
printf("token[%d]: %s\n", i, arr[i]);
return 0;
}
Your code using strlen() may appear the work in this instance but it is not correct.
strlen(arr) makes no semantic sense because arr is not a string. It happens in this case to return 5 because arr has the same address as arr[0], then you kludged it to work for the 6 word output by using the test i <= strlen(arr) in the for loop. The two values strlen(arr) and the number of strings stored in arr are not related.
The expression sizeof(arr) / sizeof(arr[0]) determines the run-time constant number arrays within the array of arrays arr (i.e. 10), not the number of valid strings assigned. It is your code's responsibility to keep track of that either with a sentinel value such as an empty string, or by maintaining a count of strings assigned.
I suggest you change tokenize to return the number of strings (currently it is inexplicably defined to return a char, but in fact only ever rather uselessly returns zero):
int tokenize( char* str, char array[][20] )
{
...
return n ;
}
Then:
int rows = tokenize( find_word_start(str), arr ) ;
for( int i = 0; i < rows; i++ )
{
printf( "token[%d]: %s\n", i, arr[i] ) ;
}

I need help understanding the code for reversing a string

I need help understanding a function for reversing the array of string.
I have been looking through a few codes, and just trying to understand it. It is a function using a pointer.
void ReverseString(char *pStr){
int length = 0;
int i = 0;
while(pStr[i]!='\0')
{
length++;
i++;
}
for (int i = 0; i < length / 2; i++) {
char temp = pStr[length - i - 1] ;
pStr[length - i - 1] = pStr[i];
pStr[i] = temp;
}
}
I am expecting it to reverse a string; I have a main function that uses it.
Strings in C are sequences of characters terminated with a zero character '\0'.
So this loop
while(pStr[i]!='\0')
{
length++;
i++;
}
calculates the length of the string that is how many characters there are in the string before the zero character. Instead of the loop you could use standard C function strlen declared in header <string.h>.
This loop
for (int i = 0; i < length / 2; i++) {
char temp = pStr[length - i - 1] ;
pStr[length - i - 1] = pStr[i];
pStr[i] = temp;
}
swaps character from the first half of the string with characters of the second half of the string. That is the first character is swapped with the last character, the second character is swapped with the before last character and so on until the middle of the string.
The function has several drawbacks. It could be written (without using standard C functions) the following way
#include <stdio.h>
char * ReverseString( char *pStr )
{
size_t n = 0;
// Calculates the number of characters in the string
// excluding the zero character.
// SO the variable n will contain the number of characters in the string.
while ( pStr[n] != '\0' ) ++n;
// Swaps characters from the first half of the string with
// the characters of the second half of the string.
// So the loop has only n / 2 iterations.
for ( size_t i = 0; i < n / 2; i++ )
{
char c = pStr[n - i - 1] ;
pStr[n - i - 1] = pStr[i];
pStr[i] = c;
}
return pStr;
}
int main( void )
{
char s[] = "Prachi Rajesh Jansari";
puts( s );
puts( ReverseString( s ) );
}
The program output is
Prachi Rajesh Jansari
irasnaJ hsejaR ihcarP

Can I change the last 4 letters of a string variable, that is already initialized?

In C, If I have a string assigned to a variable, and I want to change only the last 4 letters in that string for something else, how should I do it? strcat()? Something like:
int size;
char a[10] = "something";
size = strlen(a) - 4;
strcat(a + size, "1234");
Would that work? to get somet1234 ? or would it just be something1234 ?
Use strncpy (to prevent an extra terminator from being appended) to overwrite from a given position:
strncpy(a + size, "1234", 4);
If you really want strcat, cut the string manually for strcat() to find the starting place to concatenate:
a[size] = '\0'; // Cut the string so strcat() know where to start
strcat(a, "1234");
No, that will not work. If you used strcpy() instead of strcat() it would.
public string convertto(string abc,string replacewith,int len)
//something, 1234 and length to replace i-e 4
{
int g = strlen(abc);
int f = g - len;
j=0;
char[] temp =new char[g];
for (int i = 0; i < g; i++)
{
if (i >= f)
{
temp[i] = replaceWith[j];
j++;
}
else
{
temp[i] = abc[i];
}
}
return temp.ToString();
}
// It will return somet....

Converting a string to Upper case letters and zeros in C

I am trying to create a function that accepts a string and converts all lowercase letters to uppercase and everything else into zeros then prints the string. Here is what I have:
void upperAndZeros(char* toUpper) {
char *toReturn[(sizeof(toUpper) / sizeof(*toUpper)) + 1];
int i;
for (i = 0; toUpper[i] != '\0'; i++) {
if (toUpper[i] >= 'a' && toUpper[i] <= 'z') {
toReturn[i] = (char) toupper(toUpper[i]); //this is line 127 in the code
} else {
toReturn[i] = (char) 0;
}
}
toReturn[i] = '\0';
printf("The modified string is '%s'", toReturn);
}
But when I go to compile this I get the following error:
127:25 warning: assignment makes pointer from integer without a cast
The error you are getting is because you are trying to char in a char * array here
toReturn[i] = (char) toupper(toUpper[i]);
You want an array of char not char *. Change this line
char *toReturn[(sizeof(toUpper) / sizeof(*toUpper)) + 1];
to
char toReturn[(sizeof(toUpper) / sizeof(*toUpper)) + 1];
Another change that you should do, which was suggested in the comment is, sizeof() won't work here, as an array decays into a pointer when passed onto a function. sizeof(toUpper) would return the size of a pointer. Read this to understand the problem.
Use strlen() here, if the string pointed by toUpper is NUL terminated.
If not then send the length separately to the function as another parameter.
Lots of problems, something like this should work better:
void upperAndZeros(char* toUpper) {
char toReturn[strlen(toUpper) + 1];
int i;
for (i = 0; toUpper[i] != '\0'; i++) {
if (islower(toUpper[i])) {
toReturn[i] = (char) toupper(toUpper[i]);
} else {
toReturn[i] = '0'; // beware not 0 but char '0'
}
}
toReturn[i] = '\0';
printf("The modified string is '%s'", toReturn);
}

Returning the length of a char array in C

I am new to programming in C and am trying to write a simple function that will normalize a char array. At the end i want to return the length of the new char array. I am coming from java so I apologize if I'm making mistakes that seem simple. I have the following code:
/* The normalize procedure normalizes a character array of size len
according to the following rules:
1) turn all upper case letters into lower case ones
2) turn any white-space character into a space character and,
shrink any n>1 consecutive whitespace characters to exactly 1 whitespace
When the procedure returns, the character array buf contains the newly
normalized string and the return value is the new length of the normalized string.
*/
int
normalize(unsigned char *buf, /* The character array contains the string to be normalized*/
int len /* the size of the original character array */)
{
/* use a for loop to cycle through each character and the built in c functions to analyze it */
int i;
if(isspace(buf[0])){
buf[0] = "";
}
if(isspace(buf[len-1])){
buf[len-1] = "";
}
for(i = 0;i < len;i++){
if(isupper(buf[i])) {
buf[i]=tolower(buf[i]);
}
if(isspace(buf[i])) {
buf[i]=" ";
}
if(isspace(buf[i]) && isspace(buf[i+1])){
buf[i]="";
}
}
return strlen(*buf);
}
How can I return the length of the char array at the end? Also does my procedure properly do what I want it to?
EDIT: I have made some corrections to my program based on the comments. Is it correct now?
/* The normalize procedure normalizes a character array of size len
according to the following rules:
1) turn all upper case letters into lower case ones
2) turn any white-space character into a space character and,
shrink any n>1 consecutive whitespace characters to exactly 1 whitespace
When the procedure returns, the character array buf contains the newly
normalized string and the return value is the new length of the normalized string.
*/
int
normalize(unsigned char *buf, /* The character array contains the string to be normalized*/
int len /* the size of the original character array */)
{
/* use a for loop to cycle through each character and the built in c funstions to analyze it */
int i = 0;
int j = 0;
if(isspace(buf[0])){
//buf[0] = "";
i++;
}
if(isspace(buf[len-1])){
//buf[len-1] = "";
i++;
}
for(i;i < len;i++){
if(isupper(buf[i])) {
buf[j]=tolower(buf[i]);
j++;
}
if(isspace(buf[i])) {
buf[j]=' ';
j++;
}
if(isspace(buf[i]) && isspace(buf[i+1])){
//buf[i]="";
i++;
}
}
return strlen(buf);
}
The canonical way of doing something like this is to use two indices, one for reading, and one for writing. Like this:
int normalizeString(char* buf, int len) {
int readPosition, writePosition;
bool hadWhitespace = false;
for(readPosition = writePosition = 0; readPosition < len; readPosition++) {
if(isspace(buf[readPosition]) {
if(!hadWhitespace) buf[writePosition++] = ' ';
hadWhitespace = true;
} else if(...) {
...
}
}
return writePosition;
}
Warning: This handles the string according to the given length only. While using a buffer + length has the advantage of being able to handle any data, this is not the way C strings work. C-strings are terminated by a null byte at their end, and it is your job to ensure that the null byte is at the right position. The code you gave does not handle the null byte, nor does the buffer + length version I gave above. A correct C implementation of such a normalization function would look like this:
int normalizeString(char* string) { //No length is passed, it is implicit in the null byte.
char* in = string, *out = string;
bool hadWhitespace = false;
for(; *in; in++) { //loop until the zero byte is encountered
if(isspace(*in) {
if(!hadWhitespace) *out++ = ' ';
hadWhitespace = true;
} else if(...) {
...
}
}
*out = 0; //add a new zero byte
return out - string; //use pointer arithmetic to retrieve the new length
}
In this code I replaced the indices by pointers simply because it was convenient to do so. This is simply a matter of style preference, I could have written the same thing with explicit indices. (And my style preference is not for pointer iterations, but for concise code.)
if(isspace(buf[i])) {
buf[i]=" ";
}
This should be buf[i] = ' ', not buf[i] = " ". You can't assign a string to a character.
if(isspace(buf[i]) && isspace(buf[i+1])){
buf[i]="";
}
This has two problems. One is that you're not checking whether i < len - 1, so buf[i + 1] could be off the end of the string. The other is that buf[i] = "" won't do what you want at all. To remove a character from a string, you need to use memmove to move the remaining contents of the string to the left.
return strlen(*buf);
This would be return strlen(buf). *buf is a character, not a string.
The notations like:
buf[i]=" ";
buf[i]="";
do not do what you think/expect. You will probably need to create two indexes to step through the array — one for the current read position and one for the current write position, initially both zero. When you want to delete a character, you don't increment the write position.
Warning: untested code.
int i, j;
for (i = 0, j = 0; i < len; i++)
{
if (isupper(buf[i]))
buf[j++] = tolower(buf[i]);
else if (isspace(buf[i])
{
buf[j++] = ' ';
while (i+1 < len && isspace(buf[i+1]))
i++;
}
else
buf[j++] = buf[i];
}
buf[j] = '\0'; // Null terminate
You replace the arbitrary white space with a plain space using:
buf[i] = ' ';
You return:
return strlen(buf);
or, with the code above:
return j;
Several mistakes in your code:
You cannot assign buf[i] with a string, such as "" or " ", because the type of buf[i] is char and the type of a string is char*.
You are reading from buf and writing into buf using index i. This poses a problem, as you want to eliminate consecutive white-spaces. So you should use one index for reading and another index for writing.
In C/C++, a native string is an array of characters that ends with 0. So in essence, you can simply iterate buf until you read 0 (you don't need to use the len variable at all). In addition, since you are "truncating" the input string, you should set the new last character to 0.
Here is one optional solution for the problem at hand:
int normalize(char* buf)
{
char c;
int i = 0;
int j = 0;
while (buf[i] != 0)
{
c = buf[i++];
if (isspace(c))
{
j++;
while (isspace(c))
c = buf[i++];
}
if (isupper(c))
buf[j] = tolower(c);
j++;
}
buf[j] = 0;
return j;
}
you should write:
return strlen(buf)
instead of:
return strlen(*buf)
The reason:
buf is of type char* - it's an address of a char somewhere in the memory (the one in the beginning of the string). The string is null terminated (or at least should be), and therefore the function strlen knows when to stop counting chars.
*buf will de-reference the pointer, resulting on a char - not what strlen expects.
Not much different then others but assumes this is an array of unsigned char and not a C string.
tolower() does not itself need the isupper() test.
int normalize(unsigned char *buf, int len) {
int i = 0;
int j = 0;
int previous_is_space = 0;
while (i < len) {
if (isspace(buf[i])) {
if (!previous_is_space) {
buf[j++] = ' ';
}
previous_is_space = 1;
} else {
buf[j++] = tolower(buf[i]);
previous_is_space = 0;
}
i++;
}
return j;
}
#OP:
Per the posted code it implies leading and trailing spaces should either be shrunk to 1 char or eliminate all leading and trailing spaces.
The above answer simple shrinks leading and trailing spaces to 1 ' '.
To eliminate trailing and leading spaces:
int i = 0;
int j = 0;
while (len > 0 && isspace(buf[len-1])) len--;
while (i < len && isspace(buf[i])) i++;
int previous_is_space = 0;
while (i < len) { ...

Resources