Reverse array with using pointers in C - arrays

#include <stdio .h>
#include <stdlib .h>
int main(){
char text1 [N] ;
char reverse [N] ;
char* txtptr = text1 ;
char* revtxtptr = reverse ;
int N;
printf (”\n Enter any text here : ”) ;
scanf(”%s”, text1);
while(N> 0){
txtptr --;
*revtxtptr = *txtptr ;
revtxtptr++;
}
*revtxtptr = ’\0’;
printf (”The reverse text is : %s \n” , reverse) ;
return 0;
}
I want to see here output the reverse form of the input.
Something like
input:
CLEARLY
output:
YLRAELC
Could you help me to fix my fault?

Here are corrections to your code:
You have spaces before the .h> in the #include lines.
You should limit the size of the buffers.
N is not initialized.
N is not being decremented.
txtptr is not being placed at the end of the C string, but it is being decremented in the while loop.
scanf is not limited to the size of the buffer(s) minus 1.
You need to either find the size of the string using strlen or walk the string until you find '\0'. (forward direction instead)
You use the wrong double-quotes and single quotes ("smart" quotes)
Here is a safe code that will reverse the input array (not in-place):
#include <stdio.h>
#include <stdlib.h>
#define MAXSTR 255
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
int main() {
char text1[MAXSTR + 1];
char revbuf[MAXSTR + 1];
char* txtptr = text1;
char* reverse = revbuf + MAXSTR;
printf("\nEnter any text here : ");
scanf("%" STR(MAXSTR) "s", text1);
*reverse = '\0';
while(*txtptr) {
*--reverse = *txtptr++;
}
printf ("The reverse text is : %s \n" , reverse) ;
return 0;
}

Here you have an example function for int array.
int *reverseINTarray(int *array, size_t size)
{
int *end, *wrk = array;
if(array && size > 1)
{
end = array + size - 1;
while(end > wrk)
{
int tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return array;
}
or
int *reverseINTarray(const int *src, int *dest, size_t size)
{
int *wrk = dest;
if(src && dest && size)
{
wrk += size - 1;
while(size--)
{
*wrk-- = *src++;
}
}
return dest;
}

Your "swap two bytes" logic is ... simply ... wrong. Does this give you any ideas?
char temp;
temp = *chartxtptr;
*chartxtptr = *txtptr;
*txtptr = temp;
You can't "swap" any two bytes without using a temporary to hold the byte that is about to be replaced.

Related

Unexpected problem with Bidimensional char VLA pointer

I did a simple program that splits a string in substrings, using the whitespace as a split reference. The program was working as expected, so I've decided to put this code inside a function that is called "substring_whitespace".This function return a size_t value which is the number of substring's. The function arguments are char* buffer[] and char* string. Both are pointers, the first will store the substring's, and the second is the string that'll be splited.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
size_t substring_whitespace(char* buffer[],char* string) {
size_t initial_string_size = strlen(string) + 1;
char actual_string[initial_string_size];
char strings[initial_string_size][initial_string_size];
strcpy(actual_string,string);
size_t c = 0;
for(; c<initial_string_size; c++) {
size_t first_whitespace_index = strcspn(actual_string," ");
char substring[first_whitespace_index];
for(size_t d = 0; d<=first_whitespace_index; d++) {
if(d == first_whitespace_index)
substring[first_whitespace_index] = 0;
else
substring[d] = actual_string[d];
}
size_t actual_string_length = strlen(actual_string);
size_t new_actual_string_length = (actual_string_length - first_whitespace_index) + 1;
char new_actual_string[new_actual_string_length];
for(size_t d = 0,i = first_whitespace_index + 1; i<=actual_string_length + 1; i++,d++) {
if(i == actual_string_length)
new_actual_string[d] = 0;
else
new_actual_string[d] = actual_string[i];
}
strcpy(actual_string,new_actual_string);
strcpy(strings[c],substring);
buffer[c] = strings[c];
if(new_actual_string_length == 1)
break;
}
return ++c;\
}
int main() {
char string[1000];
fgets(string,sizeof(string)/sizeof(string[0]),stdin);
string[strcspn(string,"\n")] = 0;
char* buffer[strlen(string) + 1];
size_t buffer_length = substring_whitespace(buffer,string);
for(int d = 0; d<buffer_length; d++) {
printf("\n%s",buffer[d]);
}
}
After I test, the results were not as expected, so during my debug I detect that the char were being changed after get off the function by pointer. This behavior is only detectable if I try to print the buffer strings in the main.
strings is a local variable whose lifetime ends when the function returns. The easiest fix is to copy the string when assigning a value buffer[c]:
buffer[c] = strdup(strings[c]);
Another option is to change the design and return an array of ranges relative to your input string. For example struct range { char *s; size_t len; };, and if string is "hello world" the function could return [{string, 5}, {string+6, 5}].

Iterate through every char in string stored in an array

I am really new to C and in my first half year at university. This is my first questio on StackOverflow.
My task is to program it so every string stored in numbers is being converted into a decimal, without changing anything outside the main function.
I am now trying for the past 4 hours to solve this problem, where I want to iterate trough every char in the string I am currently to then, based on there position in comparison to the length to convert it into a decimal.
My only question here is to someone help me to understand how I can get the string length without using strlen() due to the fact I can't add #include <string.h>
This is what I got so far (getting the length of the array to iterate through every index):
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int length = sizeof(numbers);
for ( int i = 0; i < length; i++ ){
//how do i get the string size without strlen() D:
}
return 0;
}
In C, strings are really just char arrays with a special terminator character to mark the end of the string. So, say you have something like:
char *str = "hello";
This is essentially equivalent to this:
char str[] = {'h', 'e', 'l', 'l', 'o', '\0'};
Notice that \0 character at the end of the array? This is the special terminator character that C places at the end of strings. Functions like strlen() pretty much iterate through the char array looking for the first occurrence of the \0 character and then stopping.
So, you can make your own version of strlen(), say my_strlen() like this:
int my_strlen(char *str)
{
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '\0' */
while(str[len] != '\0')
len++;
/* Return the len */
return len;
}
Then within your for loop, you can just call this function. Also, note that your calculation of the size of the numbers array:
int length = sizeof(numbers);
will not give you the number of elements in the array. That code gives you the size (in bytes) or numbers which is an array of char pointers. If you want to get the number of elements, you have to divide that size by the size (in bytes) of a single element (i.e., a char pointer). So, something like this would work:
int length = sizeof(numbers) / sizeof(numbers[0]);
Your final code can look something like this:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int my_strlen(char *str) {
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '\0' */
while(str[len] != '\0')
len++;
/* Return the len */
return len;
}
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
// Notice the change here
int length = sizeof(numbers) / sizeof(numbers[0]);
for(int i = 0; i < length; i++ ){
int str_len = my_strlen(numbers[i]);
// Do what you need with str_len
}
return 0;
}
This project can be done without computing the length of the strings. How? In C, all strings are nul-terminated containing the nul-character '\0' (with ASCII value 0) after the last character that makes up the string. When you need to iterate over a string, you just loop until the character values is 0 (e.g. the nul-character)
This is how all string function know when to stop reading characters. Since you have an array-of-pointers that contains your strings, you just need to loop over each pointer and for each pointer, loop over each character until the nul-character is found.
Putting it altogether, (and noting you don't need math.h), you can do:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
int nnumbers = sizeof numbers / sizeof *numbers; /* no. of elements */
for (int i = 0; i < nnumbers; i++) {
long long unsigned number = 0;
/* you don't care about the length, strings are nul-terminated,
* just loop until \0 is found.
*/
for (int j = 0; numbers[i][j]; j++) {
number <<= 1; /* shift left */
number += numbers[i][j] == '1' ? 1 : 0; /* add bit */
}
printf ("%s = %llu\n", numbers[i], number); /* output result */
}
return 0;
}
(note: you must use a 64-bit type to hold the converted values as "1010110011010101111101111010101110110" requires a minimum of 38 bits to represent)
Example Use/Output
Simple example output converting each string to a numeric value:
$ ./bin/binstr2num
01001001 = 73
00101010 = 42
010100111001 = 1337
011111110100101010010111 = 8342167
0001010110011010101111101111010101110110 = 92790519158
01011100110000001101 = 379917
#include <stdio.h>
int main(){
char arr[20]="Hello";
int count=0;
while(arr[count]!='\0'){
count++;
}
printf("%d",count);
return 0;
}
Look at this small code, you will understand. In C a string ended with a NULL character. We can use that advantage.
There are a few ways to do it. IMO, a simple, reasonable way to implement strlen is:
size_t string_length(const char *s) { return strchr(s, '\0') - s; }
but if you're not allowed to use strlen then you're probably not allowed to use strchr either. So you just have to count. The most idiomatic way to do that is probably a bit obscure for a complete beginner, so here is a more verbose method.
Note that your computation of the number of elements in the array is invalid, and has been corrected below.
#include <stdio.h>
int
length(const char *s)
{
int len = 0;
while( *s++ ){
len += 1;
}
return len;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
int count = sizeof numbers / sizeof *numbers; /* Number of entries */
for( int i = 0; i < count; i++ ){
printf(" length of %s is %d\n", numbers[i], length(numbers[i]));
}
return 0;
}
It's pretty subjective, but IMO a more idiomatic way to write this is:
#include <stdio.h>
int
length(const char *e)
{
const char *s = e;
while( *e++ )
;
return e - s - 1;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
char **e = numbers + sizeof numbers / sizeof *numbers;
for( char **t = numbers; t < e; t++ ){
printf(" length of %s is %d\n", *t, length(*t));
}
return 0;
}

How to use pointer to split the string into two strings? C language

The function char *my(char *s, int n) takes a string s and shifts the characters of s by n places, causing the characters to wrap around the string.
For example, given the string "This is my Apple!" , a shift of n = 2 will result in
String1: "Th"
String2: "is is my Apple!"
if n<0 it will shift in negative direction.
You can just use printf to split a string. If you want the result in a char *, you have to allocate some memory and use sprintf instead.
Here is a example using sprintfand memory allocation to return a char *.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *shift(char *string, int n)
{
int len = strlen(string);
char *shiftedString = malloc(len + 1);
n %= len; // in case you shift over string length
if (n < 0) n += len; // backward shift
sprintf(shiftedString, "%s%*.*s", string + n, n, n, string);
return shiftedString;
}
int main()
{
char *result = shift("This is my Apple!", 2);
printf("shifted string : %s\n", result);
free(result);
return 0;
}
the string is actually a char-array char[]
you could use the strlen function in combination with a for loop like so.
You can put that in a function thus creating your own function that would shift letters based on input N.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "This is my Apple!";
//Initialize "n" before initializing the string variables.
int n = 2;
int len = strlen(string);
char string1[n];
char string2[len - n];
for(int i = 0;i<len;i++){
if(i<n){
string1[i]=string[i];
}else{
string2[i-n]=string[i];
}
}
printf("string = %s\n",string);
printf("string1 = %s\n",string1);
printf("string2 = %s\n",string2);
return 0;
}

Reverse a character array without changing value of number?

I have for example a string (mathematical equation in postfix notation) that looks like this: The numbers are 5.33,5.32,6.33,3.22
5.335.32*6.333.22++
I'm looking to make it into prefix notation but simply reversing the string won't work due to the fact it has to retain the value of the number.
I've thought of doing a normal character by character swap in a for loop, and when encountering a digit make that into a substring and place it on afterwards but I haven't gotten it to work properly and now I'm stuck.
My end-goal is to make a binary expression tree out of that, so if there's an easier way than doing this also please let me know.
A stack-based approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *postfix_to_prefix(const char *string) {
char operator, *stack[1024];
int s = 0, number, fraction;
const char *tokens = string;
while (1) {
if (sscanf(tokens, "%1d.%2d", &number, &fraction) == 2) {
stack[s] = malloc(sizeof("1.00"));
(void) sprintf(stack[s++], "%4.2f", number + (fraction / 100.0));
tokens += strlen("1.00");
} else if (sscanf(tokens, "%c", &operator) == 1) {
char *operand1 = stack[--s];
char *operand2 = stack[--s];
stack[s] = malloc(strlen(operand1) + strlen(operand1) + sizeof(operator) + sizeof('\0'));
(void) sprintf(stack[s++], "%c%s%s", operator, operand1, operand2);
free(operand1);
free(operand2);
tokens += sizeof(operator);
} else {
break;
}
}
return stack[--s];
}
int main() {
const char *string = "5.335.32*6.333.22++";
printf("%s\n", string);
char *inverted = postfix_to_prefix(string);
printf("%s\n", inverted);
free(inverted);
return 0;
}
OUTPUT
> ./a.out
5.335.32*6.333.22++
++3.226.33*5.325.33
>
This is a bare bones implementation with no real error checking nor other finishing touches. You'll want to check that non-communitive operations like subtraction and division come out with the operands in the correct order and reverse them if not.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char exp[] = "5.335.32*6.333.22++";
size_t len = strlen(exp);
char temp[len];
char *p = temp;
for(int i = len-1; i >= 0; ){
if(isdigit(exp[i])){
memcpy(p, &exp[i-4+1], 4);//all number have a length of 4
p += 4;
i -= 4;
} else {
*p++ = exp[i--];//length of op is 1
}
}
memcpy(exp, temp, len);//Write back
puts(exp);//++3.226.33*5.325.33
return 0;
}

Splitting strings and unscrambling them

I have an assignment that requires us to split a string and unscramble it. For example:
"rsedreve*_emth_*kema*_ot_*si*_skta_*uryo"
becomes:
"Your task is to make them reversed."
So far for code, I have just splitting the string:
char secondString[50];
char *secondString_ptr;
strcpy(secondString, "rsedreve*_*emth*_*kema*_*ot*_*si*_*skta*_*uryo");
secondString_ptr = strtok(secondString, "*_*");
while(secondString_ptr != NULL){
printf("%s ", secondString_ptr);
secondString_ptr = strtok(NULL, "*_*");
}
Output:
rsedreve emth kema ot si skta uryo
Obviously, the pattern here is to start at half the length of these tokens, add these characters to a char[] and then add the characters at the beginning of each tokens to the end. Can someone help me out and show me how to do this?
As you have split the string, you need to unscramble them. I think the easiest way to unscramble this is to swap the appropriate letters.
So you find the middle, then swap with the beginning and so on. For example, if you have "123456", you swap 1 and 4, then 2 and 5, then 3 and 6.
Here is a basic function that could do this:
char* unscramble(char *input)
{
int len = strlen(input);
int half = len >> 1;
int i;
for (i=0 ;i<half; i++)
{
int temp = input[i];
input[i] = input[half+i];
input[half+i] = temp;
}
return input;
}
Rather than simply printing each token, find the length of the token, do the unscrambling, shove it onto a stack, and print it out in reverse.
Edit: edited to be less of a complete solution but rather helpful snippets.
You can use an array, for example, as a simple 'stack'
char *pseudoStack[MAX_WORDS];
int stackPos = 0;
Add to the stack like this
pseudoStack[stackPos] = unscrambled;
stackPos++;
And print like this
for (i = stackPos - 1; i >= 0; i--) {
printf("%s ", pseudoStack[i]);
free(pseudoStack[i]);
}
Unscrambling can be done in precisely the manner you described. Don't forget to malloc so that you don't change the original string and so that you can keep the string after the loop ends.
char *unscrambled = malloc(MAX_WORD_LENGTH * sizeof(char));
int unscrambledPos = 0;
for (i = middle; i < wordLength; i++) {
unscrambled[unscrambledPos] = secondString_ptr[i];
unscrambledPos++;
}
for (i = 0; i < middle; i++) {
unscrambled[unscrambledPos] = secondString_ptr[i];
unscrambledPos++;
}
unscrambled[wordLength] = '\0';
Also don't forget the null character at the end!
While it's rather verbose, at least this way you can see the reasoning in each step.
Is there a policy on stackoverflow about homework questions though...?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
main()
{
char secondString[50];
char *secondString_ptr;
int i,j,n,stack_pointer=0;
char *Word;
char *stack[50];
strcpy(secondString, "rsedreve*_*emth*_*kema*_*ot*_*si*_*skta*_*uryo");
secondString_ptr = strtok(secondString, "*_*");
while(secondString_ptr != NULL){
n=strlen(secondString_ptr);
Word=(char *)malloc(n);
/*the second half and the first half form the meaningful word*/
/*so split the word into two part and assign to the variable. Like this*/
for(i=n/2,j=0;i<n;i++)
Word[j++]=secondString_ptr[i];
for(i=0;i<n/2;i++)
Word[j++]=secondString_ptr[i];
Word[j]='\0';
/*put all this word in the stack and increment the pointer*/
secondString_ptr = strtok(NULL, "*_*");
}
stack[stack_pointer]=NULL;
for(i=stack_pointer-1;i>=0;i--)
printf("%s ",stack[i]);
printf("\n");
}
This is the algorithm for your requirement.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int unscrambling(char *str){
char *p = strtok(str, "*_");
if(p){
char temp[50];
int len = strlen(p);
int len1 = len >> 1;
int len2 = len - len1;
//char temp[len2];
/*
memcpy(temp, p, len2);
memcpy(p, p+len2, len1);
memcpy(p+len1, temp, len2);
*/
memcpy(temp, p, len1);
memcpy(p, p+len1, len2);
memcpy(p+len2, temp, len1);
if(unscrambling(NULL))
*p = toupper(*p);
if(str)
printf("%s.\n", p);
else
printf("%s ", p);
return 0;
}
return 1;
}
int main(){
char string[50];
strcpy(string, "rsedreve*_*emth*_*kema*_*ot*_*si*_*skta*_*uryo");
unscrambling(string);
strcpy(string, "rsedreve*_emth_*kema*_ot_*si*_skta_*uryo");
unscrambling(string);
return 0;
}

Resources