pointer with equality operator ( problem! ) - c

*why equality operator with the pointer on function char (checker ) has no effect on actual string
#define MAXLINE 20
char strings[MAXLINE];
char nl[]= "\n";
char space[]= " ";
char tab[]= "\t";
char *tab_p=tab;
int i=0,j=0,c;
char *s;
//char* t;
char *checker(char *cp);//function checks for \n,\s,\t
int main()
{
while ( (c=getchar() )!= EOF )
strings[i++]=c;
s=checker(strings);//s gets address return value
while(*(s+j) != '\0'){
printf("%c",*(s+j));
j++;
}
}
char *checker( char *cp)
{
while( *(cp+i) != '\0'){
if(*(cp+i) == *tab_p) /* this condition is not applied why?*/
*(cp+i)= '\b';
i++;
}
return cp;
}
** I am trying to replace the tab in the original string with backspace and return the modified string but the equality operator have no effect on the original string .**
could anyone help me through this.

This is caused in part by abusing global variables.
When you enter checker, the value of the global i is already set to the length of the string. So the while loop is not entered.
Move all of the global variables into the functions where they're needed. Specifically, move them all to main and also add i to checker.
#define MAXLINE 20
char *checker(char *cp);
int main()
{
char strings[MAXLINE] = {0};
int i=0,j=0,c;
char *s;
while ( (c=getchar() )!= EOF )
strings[i++]=c;
s=checker(strings);
while(*(s+j) != '\0'){
printf("%c",*(s+j));
j++;
}
}
char *checker( char *cp)
{
char tab = '\t';
int i=0;
while( *(cp+i) != '\0'){
if(*(cp+i) == tab)
*(cp+i)= '\b';
i++;
}
return cp;
}

Related

void replaceLetters(char *text, char original, char new_char) should change text

I've been tryring to solve this problem for hours now.
void replaceLetters(char *text, char original, char new_char)
{
text = "Randoi";
for(int i = 0; i != '\0'; i++){
if(text[i] == original){
text[i] = new_char;
}
}
if I print out text in this function it's correct, but in the other function where this function is called the text doesn't change and i know there's something wrong with my pointers.
Please give me a hint. Tanks a lot.
Please see my code.
#include <stdio.h>
void replaceLetters(char *text, char original, char new_char)
{
for(int i = 0; text[i] != '\0'; i++)
{
if(text[i] == original)
{
text[i] = new_char;
}
}
}
int main()
{
char text[] = "Randoi";
replaceLetters(text,'n','T');
printf(text);
return 0;
}
The condition of for loop is "for(int i = 0; text[i] != '\0'; i++)"
Your function definition does not make a sense at least because you overwrote the first parameter
text = "Randoi";
with the address of a string literal and the condition in the for loop
for(int i = 0; i != '\0'; i++){
is incorrect. That is the for loop never will make iterations.
You should not use the type int for the index and the function should return the result string.
The function can be declared and defined the following way
char * replaceLetters(char *text, char original, char new_char)
{
for ( char *p = text; *p; ++p )
{
if ( *p == original ) *p = new_char;
}
return text;
}
Pay attention to that you may not use the function to change a string literal. Any attempt to change a string literal results in undefined behavior.
Here is a demonstrative progran.
#include <stdio.h>
char * replaceLetters(char *text, char original, char new_char)
{
for ( char *p = text; *p; ++p )
{
if ( *p == original ) *p = new_char;
}
return text;
}
int main(void)
{
char s[] = "character";
puts( s );
puts( replaceLetters( s, 'a', 'A' ) );
return 0;
}
The program output is
character
chArActer

Function to reverse the input string.Display the reversed string but just with pointer no brackets[],no libraries..function will change in memory

int *i;
ters_cevir(){
char *term=i;
char *som=i;
char som1;
while (*term != '\0') { term++; }
while (*som != '\0') {
som1=som*;
*term=som;
term--;
som++;
}
}
int main() {
char *isim=malloc(sizeof(char));
i=&isim;
printf("Reverse words=");
scanf("%s",isim);
printf("Kelimenizin tersi:\n ");
ters_cevir(); // When I call this, it must make the reverse one that make from memory
while (*isim != '\0') {
printf("%c",*isim);
isim++;
sayac++;
}
return 0;
}
Hi I have modified your code. Please see below also see my comments:-
void ters_cevir(char *isim){
char *term=isim;
//char *som=isim;
//char som1;
while (*isim != '\0') { isim++; }
while (*term != '\0') {
//som1=som*;
*--isim=*term++//isim was pointing to the null character so we are pre decrement that pointer and post decrement term
//here we are coping the string in reverse order in isim
//term--;
//som++;
}
}
int main() {
char *isim=malloc(50);//you need enough space to store a string. you have just allocated only one byte which was not enough
//i=&isim;
printf("Reverse words=");
scanf("%s",isim);
printf("Kelimenizin tersi:\n ");
ters_cevir(isim); // now it will work fine. Here you are passing the address of isim
while (*isim != '\0') {
printf("%c",*isim);
isim++;
sayac++;
}
return 0;
}
Your code does not compile because of syntax errors such as som1=som*;
You should pass the string as an argument to ters_cevir(); instead of a global variable i with an incorrect type int *.
After fixing these problems, ters_cevir() will still not achieve the expected result because it overwrites the string from the end with characters from the start, with an off by one error.
You could correct this by swapping characters at *som and *term, but be careful to stop when som >= term otherwise you will reverse the string twice.
Futhermore, the code in main is completely broken.
Here is a corrected version:
#include <stdio.h>
char *reverse(char *str) {
char *term = str;
char *som = str;
char c;
while (*term != '\0') { term++; }
while (som < term) {
term--;
c = *som;
*som = *term;
*term = c;
som++;
}
return str;
}
int main() {
char buf[128];
printf("String to reverse: ");
if (scanf("%127[^\n]", buf) == 1) {
printf("Reversed string: %s\n", reverse(buf));
}
return 0;
}

Remove a word from a sentence (string)

I am in the stage of preparing myself for exams, and the thing that I m least proud of are my skills with strings. What I need to do is remove a word from a sentence, without using <string.h> library at all.
This is what I've got so far. It keeps showing me that certain variables are not declared, such as start and end.
#include <stdio.h>
/* Side function to count the number of letters of the word we wish to remove */
int count(char *s) {
int counter = 0;
while (*s++) {
counter++;
s--;
return counter;
}
/* Function to remove a word from a sentence */
char *remove_word(const char *s1, const char *s2) {
int counter2 = 0;
/* We must remember where the string started */
const char *toReturn = s1;
/* Trigger for removing the word */
int found = 1;
/* First we need to find the word we wish to remove [Don't want to
use string.h library for anything associated with the task */
while (*s1 != '\0') {
const char *p = s1;
const char *q = s2;
if (*p == *q)
const char *start = p;
while (*p++ == *q++) {
counter2++;
if (*q != '\0' && counter2 < count(s2))
found = 0;
else {
const char *end = q;
}
}
/* Rewriting the end of a sentence to the beginning of the found word */
if (found) {
while (*start++ = *end++)
;
}
s1++;
}
return toReturn;
}
void insert(char niz[], int size) {
char character = getchar();
if (character == '\n')
character = getchar();
int i = 0;
while (i < size - 1 && character != '\n') {
array[i] = character;
i++;
character = getchar();
}
array[i] = '\0';
}
int main() {
char stringFirst[100];
char stringSecond[20];
printf("Type your text here: [NOT MORE THAN 100 CHARACTERS]\n");
insert(stringFirst, 100);
printf("\nInsert the word you wish to remove from your text.");
insert(stringSecond, 20);
printf("\nAfter removing the word, the text looks like this now: %s", stringFirst);
return 0;
}
your code is badly formed, i strongly suggest compiling with:
gcc -ansi -Wall -pedantic -Werror -D_DEBUG -g (or similar)
start with declaring your variables at the beginning of the function block, they are known only inside the block they are declared in.
your count function is buggy, missing a closing '}' (it doesn't compile)
should be something like
size_t Strlen(const char *s)
{
size_t size = 0;
for (; *s != '\n'; ++s, ++size)
{}
return size;
}
implementing memmove is much more efficient then copy char by char
I reformatted you code for small indentation problems and indeed indentation problems indicate real issues:
There is a missing } in count. It should read:
/* Side function to count the number of letters of the word we wish to remove */
int count(char *s) {
int counter = 0;
while (*s++) {
counter++;
}
return counter;
}
or better:
/* Side function to count the number of letters of the word we wish to remove */
int count(const char *s) {
const char *s0 = s;
while (*s++) {
continue;
}
return s - s0;
}
This function counts the number of bytes in the string, an almost exact clone of strlen except for the return type int instead of size_t. Note also that you do not actually use nor need this function.
Your function insert does not handle EOF gracefully and refuses an empty line. Why not read a line with fgets() and strip the newline manually:
char *input(char buf[], size_t size) {
size_t i;
if (!fgets(buf, size, stdin))
return NULL;
for (i = 0; buf[i]; i++) {
if (buf[i] == '\n') {
buf[i] = '\0';
break;
}
}
return buf;
}
In function remove_word, you should define start and end with a larger scope, typically the outer while loop's body. Furthermore s1 should have type char *, not const char *, as the phrase will be modified in place.
You should only increment p and q if the test succeeds and you should check that p and q are not both at the end of their strings.
last but not least: you do not call remove_word in the main function.
The complete code can be simplified into this:
#include <stdio.h>
/* Function to remove a word from a sentence */
char *remove_word(char *s1, const char *s2) {
if (*s2 != '\0') {
char *dst, *src, *p;
const char *q;
dst = src = s1;
while (*src != '\0') {
for (p = src, q = s2; *q != '\0' && *p == *q; p++, q++)
continue;
if (*q == '\0') {
src = p; /* the word was found, skip it */
} else {
*dst++ = *src++; /* otherwise, copy this character */
}
}
*dst = '\0'; /* put the null terminator if the string was shortened */
}
return s1;
}
char *input(char buf[], size_t size) {
size_t i;
if (!fgets(buf, size, stdin))
return NULL;
for (i = 0; buf[i]; i++) {
if (buf[i] == '\n') {
buf[i] = '\0';
break;
}
}
return buf;
}
int main() {
char stringFirst[102];
char stringSecond[22];
printf("Type your text here, up to 100 characters:\n");
if (!input(stringFirst, sizeof stringFirst))
return 1;
printf("\nInsert the word you wish to remove from your text: ");
if (!input(stringSecond, sizeof stringSecond))
return 1;
printf("\nAfter removing the word, the text looks like this now: %s\n",
remove_word(stringFirst, stringSecond));
return 0;
}
Your start and end pointers are defined within a block which makes their scope limited within that block. So, they are not visible to other parts of your code, and if you attempt to reference them outside their scope, the compiler will complain and throw an error. You should declare them at the beginning of the function block.
That said, consider the following approach to delete a word from a string:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int delete_word(char *buf,
const char *word);
int main(void)
{
const char word_to_delete[] = "boy";
fputs("Enter string: ", stdout);
char buf[256];
fgets(buf, sizeof(buf), stdin);
if (delete_word(buf, word_to_delete))
{
printf("Word %s deleted from buf: ", word_to_delete);
puts(buf);
}
else
{
printf("Word %s not found in buf: ", word_to_delete);
puts(buf);
}
system("PAUSE");
return 0;
}
int chDelimit(int ch)
{
return
(ch == '\n' || ch == '\t') ||
(ch >= ' ' && ch <= '/') ||
(ch >= ':' && ch <= '#') ||
(ch >= '[' && ch <= '`') ||
(ch >= '{' && ch <= '~') ||
(ch == '\0');
}
char *find_pattern(char *buf,
const char *pattern)
{
size_t n = 0;
while (*buf)
{
while (buf[n] && pattern[n])
{
if (buf[n] != pattern[n])
{
break;
}
n++;
}
if (!pattern[n])
{
return buf;
}
else if (!*buf)
{
return NULL;
}
n = 0;
buf++;
}
return NULL;
}
char *find_word(char *buf,
const char *word)
{
char *ptr;
size_t wlen;
wlen = strlen(word);
ptr = find_pattern(buf, word);
if (!ptr)
{
return NULL;
}
else if (ptr == buf)
{
if (chDelimit(buf[wlen]))
{
return ptr;
}
}
else
{
if (chDelimit(ptr[-1]) &&
chDelimit(ptr[wlen]))
{
return ptr;
}
}
ptr += wlen;
ptr = find_pattern(ptr, word);
while (ptr)
{
if (chDelimit(ptr[-1]) &&
chDelimit(ptr[wlen]))
{
return ptr;
}
ptr += wlen;
ptr = find_pattern(ptr, word);
}
return NULL;
}
int delete_word(char *buf,
const char *word)
{
size_t n;
size_t wlen;
char *tmp;
char *ptr;
wlen = strlen(word);
ptr = find_word(buf, word);
if (!ptr)
{
return 0;
}
else
{
n = ptr - buf;
tmp = ptr + wlen;
}
ptr = find_word(tmp, word);
while (ptr)
{
while (tmp < ptr)
{
buf[n++] = *tmp++;
}
tmp = ptr + wlen;
ptr = find_word(tmp, word);
}
strcpy(buf + n, tmp);
return 1;
}
If you have to do it manually, just loop over the indicies of your string to find the first one that matches and than you’ll have a second loop that loops for all the others that matches and resets all and jumps to the next index of the first loop if not matched something in order to continue the searching. If I recall accuretaly, all strings in C are accesible just like arrays, you’ll have to figure it out how. Don’t afraid, those principles are easy! C is an easy langugae, thiught very long to write.
In order to remove: store the first part in an array, store the second part in an array, alloc a new space for both of them and concatinate them there.
Thanks, hit the upvote button.
Vitali
EDIT: use \0 to terminate your newly created string.

strcat is giving me a segmentation fault error

After verifying that strcat is where the error occurs, I then check the previous example in my assignment. In my previous examples I use strcat(actually strncat) in the same fashion as I do for my following code. I am not too sure.
The purpose of my program is to loop through "string" and remove any occurances the character 'c' from string.
main.c:
char string[100]={0}, c[3];
printf("Enter a String: ");
fgets(string, 100, stdin);
if (string[98] == '\n' && string[99] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
printf("Enter a Char: ");
fgets(c, 2, stdin);
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
rmchr(string, c[0]);
header:
rmchr(char *string, char c)
{
int i=0;
char *word[100];
int s = strlen(string);
for(i=0; i<=(s-2); i++)
{
if(string[i] != c)
{
strcat(word, string[i]);
}
}
}
char *word[100];
It will hold a string in your program so use:
char word[100];
that is, an array of char instead of an array of char *.
Then strcat concatenates to a string but word is not initialized. Make it a string with:
word[0] = '\0';
Then string[i] is a character but strcat needs pointers to character arguments: to use a pointer use &string[i].
Finally the problem in your rmchr function is it has to return something, either through the arguments or via a return statement but it doesn't.
There are more than one point to mention here, like
rmchr() definition should have a return type, maybe void if you're not returning anything.
[FWIW, In that case, I wounder, how you'll make use of the local variable word]
inside rmchr(), word needs to be an array of chars, not char pointers. You need to change char * word[100] to char word[100].
In strcat(), both the arguments, needs to be a pointer. You need to use &string[i], in that case.
The following seems to compile fine but your code doesnt do quite what you said you wanted, "The purpose of my program is to loop through "string" and remove any occurances the character 'c' from string.". the function doesn't remove the character or return a copy of the string with the character excluded. I wrote a function that copies the string after removing the character and returns pointer to it. below is your code a bit modified and under it is my function
//Just a compilable version of your code, not sure if it does what u want
#include <stdio.h>
#include <string.h>
void rmchr(char *string, char c)
{
int i=0;
char word[100];
int s = (int)strlen(string);
for(i=0; i<=(s-2); i++)
{
if(string[i] != c)
{
strcat(word, (char *)(&string[i]));
}
}
}
int main(int argc, const char * argv[]) {
char string[100] = {0}, c[3];
char ch;
printf("Enter a String: ");
fgets(string, 100, stdin);
if (string[98] == '\n' && string[99] == '\0') {
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
}
printf("Enter a Char: ");
fgets(c, 2, stdin);
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
rmchr(string, c[0]);
return 0;
}
There you go, with a demo main
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* rmchr(char *string, char ch)
{
int counter = 0;
int new_size = 0;
char corrected_string[100];
while (string[counter] != '\n' && string[counter] != '\0' && string[counter] != EOF) {
if (string[counter] != ch) {
corrected_string[new_size] = string[counter];
new_size++;
}
counter++;
}
char *new_string = (char *)malloc((new_size+1) * sizeof(char));
for (int j = 0; j <= new_size; j++) {
new_string[j] = corrected_string[j];
}
return new_string;
}
int main(int argc, const char * argv[]) {
char *s = "The char 'c' will be removed";
char *new = rmchr(s, 'c');
printf("%s", new);
return 0;
}

Restarting while loop in c without integers

I'm trying to get this code to work, but I have no idea how to restart the inner while loop. How would I do it?
/*
* Return a pointer to the first occurrence of any character in <stop>
* in the given <string> or NULL if the <string> contains no characters
* in <stop>.
*****
* YOU MAY *NOT* USE INTEGERS OR ARRAY INDEXING.
*****
*/
char *find_any_ptr(char *string, char* stop) {
char *newstring = (char*)0;
while(*stop != '\0'){
while(*string != '\0') {
if(*string == *stop){
if(newstring < string || newstring != (char*)0){
string++;
}else{
newstring = string;
string++;
}
}
}
stop++;
}
return newstring; // placeholder
}
Use a temporary variable for string pointer, and use this temp variable instead inside the inner loop.
while(*stop != '\0'){
char *p = string;
while (*p != '\0') {
... /* use 'p' in place of 'string' */
}
stop++;
}
This is relatively simple using nothing but a character pointer to the string and a pointer to stop. For each character in your string, you compare against each character in stop, returning the character in string on match, or NULL if no match is found:
#include <stdio.h>
char *find_any_index(char string[], char stop[]) {
char *p = string;
char *sp = NULL;
while (*p)
{
sp = stop;
while (*sp)
{
if (*sp == *p)
return p;
sp++;
}
p++;
}
return NULL;
}
int main (int argc, char **argv) {
if (argc < 3) {
printf ("usage: %s string stoplist\n", argv[0]);
}
printf ("\n string: %s\n stop : %s\n\n", argv[1], argv[2]);
printf (" first char in string matching a char in stop: %s\n\n", find_any_index (argv[1], argv[2]));
return 0;
}
Output
$ ./bin/find_substr_str thisIsAstring mase
string: thisIsAstring
stop : mase
first char in string matching a char in stop: sIsAstring
Here is a demonstrative program that shows how the function can be written
#include <stdio.h>
char * find_any_ptr( const char *string, const char* stop )
{
const char *p, *q;
_Bool found = 0;
p = string;
do
{
q = stop;
while ( *q && *q != *p ) ++q;
} while ( !( found = *q ) && *++p );
return ( char * )( found ? p : NULL );
}
int main(void)
{
const char *p = find_any_ptr( "abc9de", "1234567890" );
if ( p ) puts( p );
return 0;
}
The program output is
9de
Only I would name the function find_any_char instead of find_any_ptr:)
This is my implementation:
#include <stdio.h>
#include <stdlib.h>
char * findany(char *string, char *stop) {
char * app;
//To avoid segmentation fault!
if (stop==NULL || string==NULL || !*stop || !*string)
return NULL;
do {
app=string;
while(*app!=0 && *app!=*stop)
app++;
stop++;
} while(*app==0 && *stop!=0);
return (*app!=0)?app:NULL;
}
int main(void)
{
char string[100];
char stop[100];
char * found;
for(;;) {
printf("Insert a string without spaces[q<Enter> to exit]: ");
scanf("%s",string);
if (!strcmp(string,"q"))
break;
printf("Insert the chars to search without spaces: ");
scanf("%s",stop);
printf("Searching any occurence of a char in \"%s\""
" inside \"%s\"\n",stop,string);
found=findany(string,stop);
printf("%s\n",(found!=NULL)?found:"NULL");
}
return 0;
}
I think that is better to use also the following way to implement the function findany():
char * _findany(char *string, char *stop) {
char * app; // to start the first loop
//To avoid segmentation fault!
if (stop==NULL || string==NULL || !*stop || !*string)
return NULL;
do {
app=stop;
while(*app!=0 && *app!=*string)
app++;
string++;
} while(*app==0 && *string!=0);
return (*app!=0)?(string-1):NULL;
}
You may observe the difference between the two functions adding the function _findany in the code above and to call the new function adding the following code after (or before) the printf in the main above.
found=_findany(string,stop);
printf("%s\n",(found!=NULL)?found:"NULL");

Resources