C Programming - Cannot Call Function More Than Once - c

I'm having trouble calling the function more than one time in my C program. The gist of the assignment is to replace the whitespaces in a sentence inputted from the user and replace it with a different character. For some reason, the program will call the same first function multiple times. I tried putting the strlen(x) in a variable inside my function, but I'm not very well versed in the C language, so I decided to leave it out of my code.
#include <string.h>
void display(char x[], char y);
void main(){
//Do not change this function
char a[100];
printf("Enter a sentence\n");
gets(a);
display(a, '*'); //To replace every space by *
display(a, '-'); //To replace every space by -
display(a, '+'); //To replace every space by +
}
void display(char x[], char y){
for(char i = 0; i < strlen(x); i++) {
if(x[i] == ' ') {
x[i] = y;
}
}
printf("%s\n", x);
}

It does not "call the same first function". You change the value of your string inside the function, so after the first run of the function the string does not have spaces. Therefore the second and third call print the string unchanged:
void display(char x[], char y){
for(char i = 0; i < strlen(x); i++) {
if(x[i] == ' ') {
// this happens only upon first call!
x[i] = y;
}
}
printf("%s\n", x);
}
Edit: to fix the issue, for example see the comment Ring Ø added and follow the advice

Related

It's not printing the new array. What could be the reason?

#include <stdio.h>
char q[50];
int doo(int p, int n, char* s) {
int i = 0, j = 0;
while (s[i] != '\0') {
if ((i < p) && (i > (p + n))) {
q[j] = s[i];
++j;
}
i++;
}
puts(p);
}
int main() {
char s[50];
int n, p;
printf("<--program by gautam-->\n");
printf("enter the string-->");
gets(s);
printf("\nenter the numbers of character to be deleted and position-->");
scanf("%d%d", &n, &p);
--p;
doo(p, n, s);
return 0;
}
The task is to delete certain elements of a string by asking the user the position and number of elements to delete. I'm trying to copy all elements except those whose position is provided by user, but I'm getting no output at all.
The fundamental error in your code is that you are using the && operator in the test inside your while loop, whereas you should be using the || operator: if either of the conditions is true, then add the character to the output string.
Also, your doo function is declared as returning an int but it doesn't return anything: I fixed this in the code below by returning j (the count of characters copied) but, as you never use that, you may want to redeclare the function as void, instead.
You are also attempting to print p with the puts function, where you most likely want to print q (I can put this one down to a typo).
Lastly: Never use the gets function! Why is the gets function so dangerous that it should not be used? Use fgets(), instead - it's much safer, as it will never read in more characters than you tell it to, so the buffer won't overflow (if you specify the correct size).
Here's a 'fixed' version of your code, with comments added where I've made changes:
#include <stdio.h>
char q[50];
int doo(int p, int n, char* s)
{
int i = 0, j = 0;
while (s[i] != '\0') {
if ((i < p) || (i > (p + n))) { // Need OR not AND here
q[j] = s[i];
++j;
}
i++;
}
q[j] = '\0'; // Add nul terminator (don't need if only calling once, but best to have it anyway)
puts(q); // Should be printing "q" (result string) NOT "p" (position).
return j; // MUST return something - here, the count of characters
}
int main()
{
char s[50];
int n, p;
printf("<--program by gautam-->\n");
printf("enter the string-->");
fgets(s, 50, stdin); // NEVER use gets - it's been removed from the language!
printf("\nenter the numbers of character to be deleted and position-->");
scanf("%d%d", &n, &p);
--p;
doo(p, n, s);
return 0;
}

Add character after specific character in string

Task is to add * after every * in string:
Input:*fsd*fds*fds*f
Output: **fsd**fds**fds**f
I found this and i am trying to replace every * with **
But it wont work.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <string.h>
int main() {
char x[256];
scanf("%s", &x);
for (char* p = x; p = strchr(p, '*'); ++p) {
*p = '*';
}
printf("%s", x);
system("pause");
return 0;
}
it only works when i use one char in this line
*p = '*';
but when i use more it does not work.
so *p = '**'; does not work.
Thanks for any help or hint.
It's easier to write the code if you just read one character at a time like this:
#include <stdio.h>
int main() {
while (1) {
int input = fgetc(stdin);
if (input == EOF) { break; }
if (input == '*') { fputc('*', stdout); }
fputc(input, stdout);
}
}
Also, since we are not dealing with memory allocations, arrays, or strings here, it is a lot easier to write safe code that will not suffer from buffer overflow bugs.
Note: Recent versions of the C standard put return 0; implicitly at the end of your main function so you don't have to write it yourself.
As I mentioned in the comments, when you replacing * with ** you are writing two characters in place of one, so it replaces the next character after *. One otherway would be to take another empty array and copy elements from input string, when you find * you can insert two ** Following snippet shows one potential solution.
#include<stdio.h>
#include <string.h>
int main() {
char x[256],y[256];
unsigned index = 0;
scanf("%s", x);
for (unsigned i = 0; i < strlen(x); i++) {
y[index++] = x[i];
if(x[i] == '*')
y[index++] = '*';
}
y[index] = '\0';
printf("%s", y);
system("pause");
return 0;
}

How to insert an extra character in a string in C

#include <stdio.h>
#include <string.h>
void replace(char a[],char b[]);
int main(void)
{
char string1[100]; char string2[100];
printf("Please enter a string:");
fgets(string1, sizeof(string1), stdin);
replace(string1, string2);
}
void replace(char a[],char b[])
{
int i;
strcpy(b,a);
for(i=0;i<strlen(a);i++)
{
if(a[i]=='a')
{
b[i+1]=a[i];
}
}
printf("%s\n",b);
}
The function of this program is to copy string1 into string2 but if there's any 'a' character in string1, it needed to be double in string2.
For example, if string1 is "aeroplane", the string2 needs to be "aaeroplaane".
However, the code above seem to change the next character after 'a' in string1 instead of simply adding it. For example, if I type "aloha", it will simply give me "aaoha" instead of "aalohaa". I've tried searching online but to no avail. I've been sticking on this problem for hours.
In order to work you must implement your replace function correctly
It should be like:
void replace(char a[],char b[])
{
int idxA = 0, idxB = 0;
for(idxA;idxA<strlen(a);idxA++, idxB++)
{
b[idxB] = a[idxA];
if(a[idxA]=='a')
{
idxB++;
b[idxB]=a[idxA];
}
}
b[idxB] = '\0';
printf("%s\n",b);
}
But you must ensure b has enough space to hold the complete string. For example, you can reserve twice the size of a, the worst case when array a has all a characters
Ok, if we are playing code golf, I would suggest:
void replace (char *a, char *b) {
while ((*b++ = *a))
if (*a++ == 'a')
*b++ = 'a';
}
;)
Mind to provide enough memory in b; if you want to play it safe, it has to be at least strlen(a)*2+1 (the case a consists only of character "a").
For the sake of brevity and elegance, here's a one liner:
void replace (char *a, char *b) { while((*b++=*a)&&(*a++!='a'||(*b++='a'))); }
;)
with
b[i+1]=a[i]
you're changing the next character to be 'a' and overwriting the next character.
What should be done is moving all the characters after b[i+1] one step forward and then changing 'a' in b[i+a]
void replace(char a[],char b[])
{
int i = 0, j = 0;
for(i=0; i<strlen(a); i++, j++)
{
b[j] = a[i];
if(a[i] == 'a')
b[++j] = a[i];
}
}
see if this works.
I wont solve it for you.
But here is what you need to look into.
if(a[i]=='a')
{
b[i+1]=a[i];
}
What it is doing is, if ith index of a array is 'a' then write ith index of a array in i+1th location of array b.
This way you are over-writing the contents of b.
You need to make a place for an additional character there only after shifting the string from that index to right.
It can be done in multiple ways.
Additionally, you might want to allocate more size (ideally twice: To cover the case when you pass a string1 with 100 'a's, the resulting string2 should hold 200 'a's) to your second array than the first one, because of obvious reasons.
You want this:
#include <stdio.h>
#include <string.h>
void replace(char a[], char b[]);
int main(void)
{
char string1[100]; char string2[100];
printf("Please enter a string:");
fgets(string1, sizeof(string1), stdin);
replace(string1, string2);
printf("%s\n", string2); // printf result from replace here
}
void replace(char a[], char b[])
{
int i, j; // using two indexes, one for a and one for b
// no strcpy needed here, copying is done in the for loop below
for (i = 0, j = 0; i < strlen(a); i++, j++)
{
b[j] = a[i]; // copy one char
if (a[i] == 'a') // if it's 'a'
{
b[++j] = a[i]; // copy it again
}
}
b[j] = 0; // terminate the destination string
// we don't printf b here but in main
}
For brevity no buffer overflow checking is done here.
There is still room for improvement though.

Recursive way of display alphabet in c

I am quite newbie in c, so I just starting off with some code, experimenting some stuff, right now I am stuck with this problem in C, creating a function that displays the alphabet in lowercase, on a single line, by ascending order, starting from the letter ’a’.
This is where I am stuck:
#include <stdio.h>
int alfabet(unsigned int i) {
if(i <= 122) {
char litera = i;
return litera;
}
return alfabet(i+1);
}
int main() {
int i = 97;
printf(alfabet(i));
return 0;
}
Here, you won't print anything really interesting. In fact, your application will crash because printf() require at least a char * parameter (a string).
Your alfabet() function seems not so bad, but you should print the letter in it :
int alfabet(unsigned int i)
{
if (i > 'z') {
// Here is the stop condition.
// If the value is higher than 122 ('z' character), we stop recursivity)
return;
}
printf("%c ", i);
// Otherwise, let's call this function with another character
return alfabet(i+1);
}
Target simplicity
void alfabet(int c) {
printf("%c", c);
if (c < 'z') alfabet(c+1);
}
called from main as
alfabet('a');
You may add a printf("\n");
the function prints the character given as parameter
you only call recursively the function with the next character to be printed if necessary, i.e. if the current character is below z.
Something like that:
#include <stdio.h>
void alfabet(char i) {
if(i < 'z')
{
alfabet(i+1);
}
printf("%c", i);
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print zyxwvutsrqponmlkjihgfedcba. Or:
#include <stdio.h>
void alfabet(char i) {
printf("%c", i);
if(i < 'z')
{
alfabet(i+1);
}
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print abcdefghijklmnopqrstuvwxyz
As you are new in this language, the basic thing to know is that each and every character on the keyboard has its own ASCII value ranging from 000 to 127 (i.e. total 128).
Now if you want to print a to z in a single line, the ASCII value for 'a' is 97 and that for 'z' is 122.
So, for printing this on screen you need to learn the basic for loop structure.The syntax for basic for loop is as follows :-
for(expr1;expr2;expr3)
{
Body of the loop;
}
Here, expr1 refers to the initial value of the variable, expr2 refers to the exit condition of the loop and expr3 refers to the increment or decrement value.
So, the code to print a to z is as follows :-
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
print_alpha();
getch();
}
void print_alpha()
{
int i;
for(i=97;i<+122;i++)
{
printf("%c",i);
}
}
int main() {
int i = 97;
printf("%c",alfabet(i));
return 0;
}
You Have to provide format specifier in printf (i.e. %c for character, %d for integer) Just check man printf in terminal.
And for printing a to z you can use for loop suggested by #Michel Jord, for printing in one line just put space in place of \n
#include <stdio.h>
void print_alphabets(char i) {
if(i>='a' && i<='z')
{
print_alphabets(i+1);
printf("%c ", i);
}
}
int main() {
char i;
scanf("%c",&i);
print_alphabets (i);
return 0;
}

Anagram project

I am having trouble trying to get the "isZero" function to detect if the word is an anagram or not. Asking if "isZero" is equal to 1 in main() it will only give me "anagram". And if i set it to 0 it will only give me "not anagram". To me it is not computing anything, it is just printing out whatever statement is true at the moment. Not sure how to solve this and could use some guidance.
#include <stdio.h>
#include <ctype.h>
#define MAX 26
void intialize(char a[], char b[], int c[]);
void setLetters(char newCount[], int newNumber[]);
void checkLetters(char b[], int newNumber[]);
int isZero(int c[]);
void getstring(char a[]);
void getString(char b[]);
int main(void)
{
char a[MAX], b[MAX];
int c[MAX];
intialize( a, b, c);
getstring(a);
getString(b);
setLetters(a, c);
checkLetters(b, c);
if (isZero(c) == 1) {
printf("anagram");
} else
printf("not anagram");
return 0;
}
void intialize(char a[], char b[], int c[])
{
int i;
for(i = 0; i < MAX; ++i) {
a[i] = '\0';
b[i] = '\0';
c[i] = 0;
}
}
void setLetters(char newCount[], int newNumber[])
{
int i, index = 0;
for(i = 0; i < MAX; ++i) {
if(isalpha(newCount[i])) {
newCount[i] = tolower(newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] +=1;
}
}
}
void checkLetters(char b[], int newNumber[])
{
int i, index;
for(i = 0; i < MAX; ++i) {
if(isalpha(newNumber[i])) {
newNumber[i] = tolower(newNumber[i]);
index = (int)(newNumber[i] - 'a');
newNumber[index] -= 1;
}
}
}
int isZero(int c[])
{
int i, j = 0;
for(i = 0; i < MAX; ++i) {
if(c[i] == 0)
j = 1;
else
return 0;
}
return j;
}
void getstring(char a[])
{
char line[MAX];
printf("Enter a string: ");
gets(line);
}
void getString(char b[])
{
char line[MAX];
printf("Enter a string: ");
gets(line);
}
With C it is mandatory that you slow down and understand what each part of each line does. There is no part of C where close enough is correct. That being said, you had an overall idea about how to approach the problem. However, it was very clear that you are just starting out in C (given the other answers and comments).
Before you start writing functions, determine what you need a function to do. Then try and determine how best to handle that task. If you need a function to get string input, then write one to do that. If you find yourself having to write one function to fill each string stop, your have just defeated the purpose of the function. Writing a function to do the same thing for a[] and another identical function for b[] makes no sense. You don't need a function to loop through all arrays setting your newly declared arrays to zero/NULL, that's what array initialization syntax is for.
Before you expect to have functions work, take the time to learn how to pass values to (and if a return is needed -- get values from) a function. When you pass an array to a function, pointer decay occurs. That means array a[] decays to *a when passed to a function. You can take advantage of this by declaring your functions to accept *a as the argument. While this isn't earth-shattering for a simple 1-D array, the decay becomes more involved with 2-D arrays and above.
In addition to figuring out which code makes sense as a function, you need to be just as exact with your logic in C as you are with its syntax. If there is any part of a line your are unsure about, look it up, look at the man page for the function you are using, or consult a language reference for your compiler (Gnu/MS), etc. to make sure you know exactly what your code does. It will save you time in the long run. The number one thing that trips new C programmers up, is trying to skim the manual or skim the book and then start writing code. The key to learning C is to just slow down.
Never, Never, Never use gets(). If you are taking a class and the teacher hands you an assignment using it, go to administration and ask for a refund. gets() is no longer part of the standard C library due to how easily it is compromised and exploited. Use fgets, getline, or scanf (read the entire section on proper use of the scanf format string if you chose to use it). It is a fine function, but it has many, many pitfalls just waiting for someone that partially understands its use.
That being said, you had the overall logic for one approach to anagrams. Below I've provided an example of the points above in sorting out your code. Take the time to read through it and understand why I made the changes I did. Additionally, I added a quick length check for the words input. If they are not the same length, no need to go further. Let me know if you have questions. There are a lot of good folks here that are happy to help.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 26
void setLetters(char *newCount, int *newNumber);
void checkLetters(char *newCount, int *newNumber);
int isZero (int *c);
void getstring (char *a);
int main (void)
{
char a[MAX] = {0}; /* initialize all to zero/NULL */
char b[MAX] = {0};
int c[MAX] = {0};
getstring(a);
getstring(b);
printf ("\n You entered:\n\n a: %s\n b: %s\n\n", a, b);
/* test lengths - if differ, not anagram */
if (strlen(a) != strlen(b)) {
printf (" Lenghts differ, cannot be an anagram.\n\n");
return 1;
}
setLetters (a, c); /* set key array (c) */
checkLetters (b, c); /* check key array (c) */
if (isZero(c))
printf(" The words form an anagram.\n\n");
else
printf(" The words are not and anagram.\n\n");
return 0;
}
void setLetters (char *newCount, int *newNumber)
{
int i = 0;
int index = 0;
for (i = 0; i < MAX; ++i) {
if (isalpha (newCount[i])) {
newCount[i] = tolower (newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] +=1;
}
}
}
void checkLetters(char *newCount, int *newNumber)
{
int i = 0;
int index = 0;
for (i = 0; i < MAX; ++i) {
if (isalpha (newCount[i])) {
newCount[i] = tolower (newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] -= 1;
}
}
}
int isZero (int *c)
{
int i = 0;
for (i = 0; i < MAX; ++i)
if (c[i] == 1)
return 0;
return 1;
}
void getstring (char *a)
{
printf ("\n Enter a string: ");
scanf ("%[^\n]%*c", a);
}
output:
$ ./bin/anaproj
Enter a string: yekcim
Enter a string: mickey
You entered:
a: yekcim
b: mickey
The words form an anagram.
$ ./bin/anaproj
Enter a string: yekcim
Enter a string: mickez
You entered:
a: yekcim
b: mickez
The words are not and anagram.
void getstring(char a[]);
This API is not doing what you intend to do.
This has a local variable line and your are reading a string to it and the char array in main() i.e. a is never been filled up with anything.
You continue to use the char array a thinking the values are filled in it by calling getstring() which is not happening. You need to fix this first and later work on the algorithm for anagram.
There is something called pass by reference which might help you.

Resources