insert a particular char into the string - c

for ex: if the string="EXAM"
insert a char'x' after every char of a string
output must be string="EXXXAXMX".i have done program for that but i stored a string and then i inserted 'x'.but i want the pgm to get input string from user and insert a char 'x' after every char of that string.how to do it?
#include<stdio.h>
#include<conio.h>
#include<string.h>
void strexpand(char [],char []);
void main()
{
char name[]="EXAM";
int length;
clrscr();
length=strlen(name);
printf("\n\tName=%s Length=%d",name,length);
strexpand(name);
getch();
}
void strexpand(char name[])
{
int i;
while(name[i]!='\0')
{
i++;
}
if(name[i]=='\0')
{
name[8]=name[4];
name[6]=name[3];
name[4]=name[2];
name[2]=name[1];
name[1]='x';
name[3]='x';
name[5]='x';
name[7]='x';
printf("\n\n\tAltered string is=%s",name);
}
}

It should be something like this , the new string will be always 2 times bigger than the original , so we should allocate it as 2 times bigger string , and then just copy as i said on comments.
char* strexpand(char name[])
{
int length=0;
int i=0 ,j=0;
char* retValue =null;
while(name[length]!='\0')
{
length++;
}
length++;
retValue = malloc (sizeof(char* length * 2));
if(!retValue)
return null;
for(i=0;i<length;i++,j+=2)
{
retVal[j] = name[i];
retVal[j+1] = 'x';
}
//at this point j did got +=2
retVal[j] = '\0';
return retVal;
}

Fix
#include<stdio.h>
#include<conio.h>
#include<string.h>
void strexpand(char []);
void main()
{
char name[9];
strcpy(name, "EXAM");
int length;
length=strlen(name);
printf("\n\tName=%s Length=%d",name,length);
strexpand(name);
getch();
}
void strexpand(char name[])
{
int i=0;
while(name[i]!='\0')
{
i++;
}
if(name[i]=='\0')
{
name[7]=name[3];
name[5]=name[2];
name[3]=name[1];
name[1]=name[0];
name[0]='x';
name[2]='x';
name[4]='x';
name[6]='x';
name[8] = '\0';
printf("\n\n\tAltered string is=%s",name);
}
}
note1: This code assumes that the string has at most has 8 characters.
note2: Arrays are indexed from 0. The first element is array[0]
note3: the line name[8] = '\0'; takes care of closing the string since C strings are null-terminated. It is important to know that to store n chars in a C string you always need n+1 bytes.
Some explanation
void strexpand(char name[])
{
int i;
while(name[i]!='\0')
{
i++;
}
This part is problematic, becasue i will have some junk value. It should be
void strexpand(char name[])
{
int i = 0;
while(name[i]!='\0')
{
i++;
}
Also when using strexpand you assue that its parameter has at least 9 elements because of this line:
name[8]
When you give it a smaller string than 9 elements (as in your code) the code will try to access elements outside of allocated space, which will result in a segfault.
So, when you called it with "EXAM" the parameter looked like this in memory:
['E','X','A','M','\0']
Given this, name[5] was already problematic.

Related

Invoking the function renders an error; what explains this?

A function I created, which I refer to as string_deletion, deletes occurrences of a specific substring and shifts the string leftwards by the length of the substring. The function accepts two parameters: the pointer to the location in the array wherein the first letter of the substring is encountered, and the length of the word.
Here is the function:
void string_deletion(char *s, int m)
{
char *index=s+m;
while(*index!=0)
{
*(index-m)=*(index++);
}
*(index-m)=0;
}
The function shifts all the characters after the substring leftwards by an amount dependent on the length of the substring, which has been denoted by m. I have set the index pointer to point to the character that occurs immediately after the occurrence of the substring, and this is the mark from where the shifting commences. The loop is executed until a NUL character is encountered, after which it exits the loop. At the culmination, the NUL is appended to the end of the string.
Whereas the other parts of the main code work seamlessly, invoking this specific function, as and when necessary, makes the program cease working and it yields an error. What explains this?
Here's the complete code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
int string_len(char *s)
{
int i=0;
char *m=s;
while(*m!=0)
{
i++;
m++;
}
return i;
}
void word_enter(char *word_search)
{
char r;
char *m=word_search;
while((r=getchar())!=EOF)
{
if(r=='\n')
{
*m=0;
break;
}
else
{
*(m++)=r;
}
}
}
void string_disp(char *s)
{
char *d=s;
while(*d!=0)
{
putchar(*(d++));
}
}
int string_comp(char *s, char *m)
{
int stringlength_one=string_len(s);
int stringlength_two=string_len(m);
char *s_one=s;
char *s_two=m;
if(stringlength_one!=stringlength_two)
{
return 1;
}
else
{
while(*s_one!=0)
{
if(*s_one!=*s_two)
{
return 1;
}
s_one++;
s_two++;
}
}
return 0;
}
void string_deletion(char *s, int m)
{
char *index=s+m;
while(*index!=0)
{
*(index-m)=*(index++);
}
*(index-m)=0;
}
void string_search(char *s,char *d)
{
char *m=s;
char word_buffer[20];
char *buffer_index=word_buffer;
while(m!=&s[string_len(s)-string_len(d)+1])
{
buffer_index=word_buffer;
if(*m==*d)
{
int i=0;
char *r=m;
while(i<=string_len(d) && *r!=0)
{
*(buffer_index++)=*(r++);
i++;
}
*buffer_index=0;
if(string_comp(word_buffer,d)==0)
{
printf("\nInvoking deletion sequence\n");
string_deletion(m,string_len(d));
}
}
m++;
}
}
int main(void)
{
int pos;
char main_string[100],word[20];
printf("Enter the main string: ");
word_enter(main_string);
printf("\nEnter the string you wish to delete: ");
word_enter(word);
string_search(main_string,word);
string_disp(main_string);
exit(EXIT_SUCCESS);
}
*(index-m)=*(index++)
This is undefined behaviour. If you use a post- or pre-inc/decrement, don't use the same variable in the same expression again.
index[-m] = *index;
++index;
The problem (or, at least, one problem) is in your string_search function. The substring you extract from the given s argument is one character too long; thus, you won't get a match with the given d argument, unless you are very lucky.
To fix the problem, change the test condition in the while loop from i <= string_len(d) to i < string_len(d), like this:
void string_search(char* s, char* d)
{
char* m = s;
char word_buffer[20];
char* buffer_index = word_buffer;
while (m != &s[string_len(s) - string_len(d) + 1]) {
buffer_index = word_buffer;
if (*m == *d) {
int i = 0;
char* r = m;
while (i < string_len(d) && *r != 0) { // Use i < string_len ... not i <=
*(buffer_index++) = *(r++);
i++;
}
*buffer_index = 0;
if (string_comp(word_buffer, d) == 0) {
printf("\nInvoking deletion sequence\n");
string_deletion(m, string_len(d));
}
}
m++;
}
}
Also, be sure to address the issue of undefined behaviour highlighted in this answer (my MSVC compiler didn't spot that one, but clang-cl did)!
I would not reinvent the wheel:
char *string_deletion(char *s, size_t m)
{
memmove(s, s + m, strlen(s+m) + 1);
return s;
}

how can i use pointer to move inside of this array (function) instead of array subscribting

my question is at the generate acronym function, how can i make this function work in a pointer arithmetic way instead of array subscripting.
without messing up with the structures itself, the prof prhobited array subscribting so i have to do it with pointer arithmetic instead, anyone can land a hand?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define B 2
#define N 8
typedef struct {
int course_id;
int course_quota;
char course_name[50];
char course_code[6];
char course_acronym[N];
}course_t;
void generate_course_code(char *course_code, int course_id);
void generate_course_acronym(char *, char *);
void display();
course_t courses[B];
int main() {
int i;
for(i = 0; i < B; i++) {
printf("Enter the course name: ");
fgets(courses[i].course_name, sizeof(courses[i].course_name), stdin);
generate_course_acronym(courses[i].course_name, courses[i].course_acronym);
printf("Enter the course Quota: ");
scanf("%d", &courses[i].course_quota);
while ('\n' != getchar())
{
}
courses[i].course_id = i;
generate_course_code(courses[i].course_code, courses[i].course_id);
}
display();
return 0;
}
void generate_course_code(char *course_code, int course_id) {
char str[6];
course_id++;
strcpy(course_code, "CSE");
if (course_id < 10) {
sprintf(str, "0%d", course_id);
}
else
sprintf(str, "%d", course_id);
strcat(course_code, str);
}
void generate_course_acronym(char *course_name, char *course_acronym) {
int j = 0;
char *p = course_name;
for (course_acronym[j++] = toupper(*p); *p != '\0'; p++)
if (*p == ' ') course_acronym[j++] = toupper(*(++p));
course_acronym[j] = '\0';
}
void display() {
int x;
for (x = 0; x < B; x++) {
printf("%d. %s - %s (%s) - %d \n", ++courses[x].course_id, courses[x].course_code, courses[x].course_name, courses[x].course_acronym, courses[x].course_quota);
}
}
Because the function arguments are provided as pointers, they can be used as is to achieve your goal using pointer arithmetic as shown below:
(explanations in comments).
void generate_course_acronym(char *course_name, char *course_acronym)
{
*course_acronym = (char)toupper(*course_name); //initialize acronym to capitalized form of first character
while(*course_name) //test for end of string (NULL)
{
if(*course_name == ' ') // detect spaces between strings
{
course_acronym++; // advance acronym pointer
course_name++; // advance source pointer beyond space.
*course_acronym = (char)toupper(*course_name); // assign next acronym character
}
course_name++; // advance source to next address location
}
course_acronym++; // advance pointer to one location beyond end of acronym
*course_acronym = '\0'; // NULL terminate, making acronym a new string
}
Note: The calling function must pass enough space in course_acronym to accommodate 1 byte for each word in course_name, + 1 extra byte. For example, if course_name is defined as:
char course_name[]={"This is a fine programming class"};
then course_acronym must be defined with space for at least 7 bytes. (count of words + 1 for NULL termination)

return pointer from a function in c

Write function that gets a string s and char c that checks whether the char shows in s, if yes return a pointer to the first place that c shows in s
Here is my code. I am not sure what I did about "return the pointer", is this correct?:
#include <stdio.h>
char *foo(char s[], char c)
{
int i;
char *ptr;
for(i=0;s[i];i++)
{
if(s[i]==c)
{
printf("result: %d",i);
*ptr=i;
return ptr;
}
}
}
void main()
{
char s[]="Error404";// some string
char c='r';// some char
foo(s,c);
}
First of all, your specification is unclear. Before you start coding, make sure that the specification makes sense. It doesn't say what to do if you don't find the character, so you can't write this function before you know that.
Your function must always return something, even if the character was not found. A common way to implement this would be to return a null pointer in that case.
Your pointer should point at the found character, not at i which is an integer, that doesn't make any sense.
Correct the code into something like this:
char* foo (char s[], char c)
{
char *ptr = NULL;
for(int i=0; s[i]!='\0'; i++)
{
if(s[i]==c)
{
ptr = &s[i]; // point at the address of item number i in s
break;
}
}
return ptr; // will return NULL if not found, otherwise a pointer to the found item
}
If s is a string, then s[i] represents the ith char in the string, while s + i represents a pointer to the ith char in the string. So you want to return s + i. You probably also want to return NULL if the char is not found.
#include <stdio.h>
char *foo(char s[], char c)
{
int i;
for(i = 0; s[i]; i++)
{
if(s[i] == c)
return (s + i);
}
return (NULL);
}

C: Take parts from a string without a delimiter (using strstr)

I have a string, for example: "Error_*_code_break_*_505_*_7.8"
I need to split the string with a loop by the delimiter "_*_" using the strstr function and input all parts into a new array, let's call it -
char *elements[4] = {"Error", "code_break", "505", "7.8"}
but strstr only gives me a pointer to a char, any help?
Note: the second string "code_break" should still contain "_", or in any other case.
This will get you half-way there. This program prints the split pieces of the string to the standard output; it does not make an array, but maybe you can add that yourself.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void split(const char * str, const char * delimiter)
{
char * writable_str = strdup(str);
if (writable_str == NULL) { return; }
char * remaining = writable_str;
while (1)
{
char * ending = strstr(remaining, delimiter);
if (ending != NULL) { *ending = 0; }
printf("%s\n", remaining);
if (ending == NULL) { break; }
remaining = ending + strlen(delimiter);
}
free(writable_str);
}
int main(void) {
const char * str = "Error_*_code_break_*_505_*_7.8";
const char * delimiter = "_*_";
split(str, delimiter);
return 0;
}
Here is a function that splits a string into an array. You have to pass the size of the array so that the function won't overfill it. It returns the number of things it put into the array. What it puts into the array is a pointer into the string that was passed. It modifies the string by inserting null characters to end the pieces - just like strtok does.
#include<string.h>
#include<stdio.h>
int split(char *string, char *delimiter, char* array[], int size)
{
int count=0;
char *current=string;
char *next;
while(current && *current!='\0')
{
next=strstr(current,delimiter);
if(!next)break;
*next='\0';
if(count<size) array[count++]=current;
current=next+strlen(delimiter);
}
if(count<size) array[count++]=current;
return count;
}
int main()
{
char string[100]="Error_*_code_break_*_505_*_7.8";
char *array[10];
int size=split(string,"_*_",array,10);
for(int i=0;i<size;i++) puts(array[i]);
return size;
}

Reverse a string recursively in C - using a pointer to string only

i'm trying to reverse a string using recursion and a single pointer to that string.
My idea is to traverse the string from both edges, raising the pointer and inserting '\0's at the end of the string. For example - given a string 'abcde\0' - replace "chars" before the middle of the string, and insert '\0' after -> recursive calls -> when "stop condition" is reached, original string should be like this - 'edc\0\0\0' - and half of chars stored as temp variable, in stack. When turning back and popping the stack, these chars should overwrite the '\0' in reverse order. This is the idea.
This is my code so far, but I can't get it work - please help me understand, what do I miss. I have a '\0' in the middle of string that I can't figure out how to rewrite it. (I guess this is the major problem)
Thanks in advance.
#include <stdio.h>
#include <string.h>
void rev_str(char* _str);
int main()
{
char str[]="abcde";
puts("Str before:");
puts(str);
rev_str(str);
puts("Str after");
puts(str);
return 0;
}
void rev_str(char* _str)
{
int len=strlen(_str);
char temp=*_str;
if(len>1)
{
*_str = _str[len-1];
_str[len-1]='\0';
rev_str(++_str);
}
_str[len-1]=temp;
}
I won't debug your code, however this might help you understand things better -
http://www.programmingsimplified.com/c-program-reverse-string
Examples taken from page -
C program to reverse a string using pointers
Now we will invert string using pointers or without using library function strrev.
#include<stdio.h>
int string_length(char*);
void reverse(char*);
main()
{
char string[100];
printf("Enter a string\n");
gets(string);
reverse(string);
printf("Reverse of entered string is \"%s\".\n", string);
return 0;
}
void reverse(char *string)
{
int length, c;
char *begin, *end, temp;
length = string_length(string);
begin = string;
end = string;
for (c = 0; c < length - 1; c++)
end++;
for (c = 0; c < length/2; c++)
{
temp = *end;
*end = *begin;
*begin = temp;
begin++;
end--;
}
}
int string_length(char *pointer)
{
int c = 0;
while( *(pointer + c) != '\0' )
c++;
return c;
}
C program to reverse a string using recursion
#include <stdio.h>
#include <string.h>
void reverse(char*, int, int);
int main()
{
char a[100];
gets(a);
reverse(a, 0, strlen(a)-1);
printf("%s\n",a);
return 0;
}
void reverse(char *x, int begin, int end)
{
char c;
if (begin >= end)
return;
c = *(x+begin);
*(x+begin) = *(x+end);
*(x+end) = c;
reverse(x, ++begin, --end);
}
rev_str(++_str);
This is the problem. You're modifying _str here so when you do _str[len-1]=temp at the end, you're writing to the wrong location. Change it to
rev_str(_str + 1);
Just change the code rev_str(++_str); into rev_str(_str+1);. The ++_str equal to _str += 1, it will change the pointer char *_str. But _str+1 will only initialize the formal param, and will not change the 'char *str'. I hope this can help you.

Resources