How to change numbers in an array to symbols - c

I am trying to find a good way to convert digits of a string in an array to a # symbol.
I would like to be clear, this is for a homework assignment. I am asking for help because not only am I running into roadblocks that I would like to overcome; but I want to understand the relationship between arrays and functions as well.
I have done some code, shown below, but I feel like I am confusing myself on the relationship between calls in arrays when they are within a function.
Here is what I have done:
void coverNumbers(char s[]) {
char num;
if (s[num] >= '0' || s[num] <= '9')
num = '#';
}
I feel like I am so close to having a solution.
If I type in 43ll0 within the array, I want the 43ll0 to become ##ll#.
Thank you for your help everyone, and have a wonderful night!

You are going about this the wrong way. You need to loop over the string to check and replace each character individually.
Try This
void coverNumbers(char s[]) {
for (int i = 0; s[i]; i++)
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
}
You have additional logic mistakes. If you have some questions on why I changed a specific thing please ask in the comments.

Assuming covernumbers receives a C string, ie a pointer to a char array terminated by a null byte '\0', you should just iterate on all characters and perform the modification. Note however that you used || instead of && to test for digits. s[num] is a digit if it is >= '0' and <= '9'.
Here is a corrected version:
void coverNumbers(char s[]) {
for (size_t i = 0; s[i] != '\0'; i++) {
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
}
}
You can also use the pointer and increment it. void coverNumbers(char s[]) and void coverNumbers(char *s) are equivalent and the second version make it more obvious that s is a pointer, not an actual array.
void coverNumbers(char *s) {
while (*s) {
if (*s >= '0' && *s <= '9')
*s = '#';
s++;
}
}

Welcome to Stack Overflow!
You should not use stack overflow for such kind of problems. But you can always ask questions on the issues you are facing, if the similar question is not already been asked by others.
SOLUTION:
Algorithm:
Get the length of the string
Iterate each character in the string
Based on the value in current position (index) of string, replace with '#' if it's a digit.
Print the output
Code:
void coverNumbers(char s[]) {
int len = strlen(s);
for (int i = 0; i < len; i++)
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
printf("%s", s);
}

Related

What's wrong with this string checking program?

I want to make this program only English in the string, but when the end of the string ends in English, another strange word is added. Why is that?
int main(void)
{
char line[100];
char line2[100];
printf("Please enter a string: ");
gets_s(line, sizeof(line));
int k = 0;
for(int i = 0; line[i] != '\0'; ++i) {
while(line[i] >= 'A'&& line[i] <= 'z') {
line2 [k++] = line[i++];
}
}
line2[k] = '\0';
printf("string: %s\n", line2);
return 0;
}
for(int i = 0; line[i] != '\0'; ++i) {
while(line[i] >= 'A'&& line[i] <= 'z') {
line2 [k++] = line[i++];
}
}
replacing the for loop with a while loop...
int i = 0;
while (line[i] != '\0') {
while (line[i] >= 'A' && line[i] <= 'z') {
line2 [k++] = line[i++];
}
i++;
}
So, here you can see if the inner while goes to the '\0' i gets incremented past the terminating zero byte.
The basic problem is that you put responsibility for incrementing i in two different places. As a result, it can get incremented more than you want -- for example, so as to skip over the string terminator.
It appears to me that you have caused this problem for yourself by making the code more complicated than it needs to be. Why use a two-loop nest to iterate over a single string? In fairness, there are indeed potential reasons to do that, but none of them appear to be in evidence here. I suggest changing the inner while loop to an if statement, and not incrementing i within:
for (int i = 0; line[i] != '\0'; ++i) {
if (line[i] >= 'A' && line[i] <= 'z') {
line2[k++] = line[i];
}
}
Note how there is only one place where i is incremented in that variation.
Note also that there may be characters that satisfy c >= 'A' && c <= 'z' but are not letters. I say "may" because C is not specific to a particular character set or encoding, but in practice, it is virtually certain that there are non-letter characters in that range on your implementation. Perhaps isalpha((unsigned char) line[i]) would be a better fit, though it is not, by itself, without character set related issues.

convert a string cointaing a base 10 number to an integer value

I am fairly new to programming and I am trying to convert a string containing a base 10 number to an integer value following this pseudo algorithm in c.
start with n = 0
read a character from the string and call it c
if the value of c is between '0' and '9' (48 and 57):
n = n * 10 +(c-'0')
read the next character from the string and repeat
else return n
here is the rough basics of what i wrote down however I am not clear on how to read a character from the string. i guess im asking if i understand the pseudocode correctly.
stoi(char *string){
int n = 0;
int i;
char c;
for (i = 0;i < n ; i++){
if (c[i] <= '9' && c[i] >= '0'){
n = n *10 +(c - '0')}
else{
return n
}
}
}
You were close, you just need to traverse the string to get the value of each digit.
Basically you have two ways to do it.
Using array notation:
int stoi(const char *str)
{
int n = 0;
for (int i = 0; str[i] != '\0'; i++)
{
char c = str[i];
if ((c >= '0') && (c <= '9'))
{
n = n * 10 + (c - '0');
}
else
{
break;
}
}
return n;
}
or using pointer arithmetic:
int stoi(const char *str)
{
int n = 0;
while (*str != '\0')
{
char c = *str;
if ((c >= '0') && (c <= '9'))
{
n = n * 10 + (c - '0');
}
else
{
break;
}
str++;
}
return n;
}
Note that in both cases we iterate until the null character '\0' (which is the one that marks the end of the string) is found.
Also, prefer const char *string over char *string when the function doesn't need to modify the string (like in this case).
Congrats on starting your C journey!
One of the most important aspects of strings in C is that, technically, there are none. A string is not a primitive type like in Java. You CAN'T do:
String myString = "Hello";
In C, each string is just an array of multiple characters. That means the word Hello is just the array of [H,e,l,l,o,\0]. Here, the \0 indicates the end of the word. This means you can easily access any character in a string by using indexes (like in a normal array):
char *myString = "Hello";
printf("%c", myString[0]); //Here %c indicates to print a character
This will then print H, since H is the first character in the string. I hope you can see how you can access the any character in the string.

count_word function returns 0 in C

This is my first post on stack overflow :)
I didn't find relevant post to my issue despite numerous posts on "counting words".
I started C 2 weeks ago. I have to return the number of words in a string, this is part of a larger exercise I m working on at the moment. I can't figure out why it doesn't work and I am kindly asking for some tips here.
ft_strlen(char *str) //counting nb of char in the string
{
int size;
size = 0;
while (str[size])
size++;
return (size);
}
int ft_word_count(char *str)
{
int i;
int size;
int count_word;
i = 0;
size = ft_strlen(str);
count_word = 0;
while (str[i] < size - 1) //counting nb of words in the string, I added "-1" to size to get rid of the '\0'
{
if (i <= 32 || i > 126 ) //defining what will make a word
count_word++;
i++;
}
return (count_word);
}
int main(void)
{
char str[]="Meine Frau liebt grosse Pferde";
ft_strlen(str);
printf("%d", ft_word_count(str));
return (0);
}
it returns 0 instead of 5, strangely, don't figure out why.
If I just use my strlen, it returns "30", as expected. So something is wrong with ft_word_count
Compiled with gcc.
Syntax is not concise but is part of the norm asked by my school.
thanks for your input
Charles
you should ignore multiple spaces for counting correct
i=0;
count_word=0;
while(str[i]>0)
{
if((str[i]!= ' '))
{
if(!toggle && str[i]!= ' ')
count_word++;
toggle=1;
}
else
toggle=0;
i++;
}
I believe that you meant to use logic more like this:
if(str[i] <= 32 || str[i] > 126) count_word++;
In the code that you posted, you are looking at the value of your index, not the character value in the string.
Even so, this is not why you are receiving "0" as a result. The cause of this is your while condition. You are checking to see if the numeric ASCII value within the string is greater than the length of the string... which I can assure you, it is. Therefore, you also want to change your white to be:
while(i < size - 1)
Personally, I would likely have checked for \n, space and \t instead, but to each his own!
The problem is these lines
while (str[i] < size - 1) // Here you compare the individual chars and
// the length of the string. That makes
// no sense
{
if (i <= 32 || i > 126 ) // Here you compare the index i and some
// fixed numbers. That makes no sense
count_word++;
i++;
}
It seems you have swapped the two, i.e. you use str[i] when you should use i and you use i when you should use str[i]
So if you change your code to:
while (i < size - 1)
{
if (str[i] <= 32 || str[i] > 126 )
count_word++;
i++;
}
You'll see that things start to make more sense. That code will print 4. That is still wrong but now you have some code that you can continue with.
A simple approach could be:
while (i < size - 1)
{
if (str[i] == ' ')
count_word++;
i++;
}
count_word++;
That code will print 5. However, the code is too simple as it count double spaces as words.
In other words - you need to add more code to handle such case but I guess that is part of the learning process. Good luck.
Error Part
while (str[i] < size - 1)
Here its checking with the ascii value at that place of string which will always be false and hence loop is not running.
Correct Way
while (i < size - 1)
{
if (str[i] == ' ')
count_word++;
i++;
}
count_word++;
There are multiple problems in your code:
while (str[i] < size - 1) is incorrect as you are comparing the value f the character to the size of the string instead of the index: it should be while (i < size).
if (i <= 32 || i > 126 ) is incorrect: it is not a proper way to check for word separators as non ASCII characters will not be considered part of the word and the encoding might not be ASCII anyway. You should instead use isspace() from <ctype.h>.
Furthermore, counting the spaces is not a way to count the words. You should instead count the number of transitions from space to non-space.
Here is a simpler version:
#include <ctype.h>
#include <stdio.h>
int ft_word_count(const char *str) {
unsigned char c, last = ' ';
int count = 0;
for (int i = 0; (c = str[i]) != '\0'; i++) {
if (!isspace(c) && isspace(last))
count++;
last = c;
}
return count;
}
int main(void) {
char str[] = "Meine Frau liebt grosse Pferde";
printf("%d\n", ft_word_count(str));
return 0;
}

Creating a toUpper function in C

I'm creating my own toUpper function in C, but keep getting a segmentation fault every time I attempt to run it. Can anyone provide me with any hints as to how to fix this problem?
int toUpper(char *str)
{
int i;
for(i=0;i< i <= strlen(str); i++) {
if(str[i] >= 97 && str[i] <= 122) {
str[i] = str[i] -32;
}
}
return(str[i]);
}
int main()
{
char string[20];
printf("Enter any string:\n");
scanf("%s", string);
char result= (char)(toUpper(string));
printf("The string in upper case is:%s\n", result);
}
You're running off the end of the string:
for(i=0;i< i <= strlen(str); i++) {
^--
e.g. a 10 char string has characters 0->9, but you're looping 0->10. Change <= to < so you stop at 9.
Plus, you haven't set any limit on your scanf, so if someone enters a 21 char string, you'll exceed the storage you've allocated the string array.
Recommend changing toUpper() to:
char *toUpper(char *str) {
size_t len = strlen(str);
size_t i;
for (i = 0; i < len; i++) {
if (str[i] >= 'a' && str[i] <= 'z') {
str[i] = str[i] - 'a' + 'A';
}
}
return str;
}
Use correct index range i < strlen(str) vs. i <= strlen(str). This is the main issue. #Marc B
Change return type. Suggested by #Weather Vane. like strcpy(), strcat()
Calculate string length once, rather than many times.
Use literals that match your goal: 'a' instead of 97. #marsh
Use size_t for index and length. That is the type return by strlen() and is the best type to use for array access. Makes a difference with huge strings, but not with these simple examples.
This code does depend on ASCII. This is often OK, but not completely portable.
Change 32 to -'a' + 'A' per #user295691
printf("The string in upper case is:%s\n", result);
result should be a char * but is a char. This is probably where your seg fault is happening. Other places include:
scanf("%s", string);
if the inputted string is longer than 19 chars, you could have problems due to string only being 20 chars long
for(i=0;i< i <= strlen(str); i++) {
if str for whatever reason doesn't have an ending 0, you could seg fault there as well.
Another major issue in the code is the for loop statement.
for(i=0;i< i <= strlen(str); i++)
^ ^
It's probably a typo, but the i < i < wont work.

lower case to Uppercase function - C

I've written this function to convert a lowercase str that is preset into it's uppercase variant. I've tried every different configuration I know that converts lower case to uppercase, however when I print it. It still ends up in lower case. So I am a tad Stuck.
char* stoupper(char str[]);
char str[100]= "uppercase";
printf("%s" , stoupper(str)); // Test to make sure it is working
char* stoupper(char str[])
{
int i = 0;
while(str[i] != '\0')
{
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] + ('A' - 'a');
i++;
}
return str;
}
/* I've tried various variations of this function this is just the one i had first */
Your code only modifies already-uppercase letters, and turns them into who-knows-what (well, I'm sure you could figure out with an ASCII table). If you want to operate on lowercase letters, you need to change your if condition:
if (str[i] >= 'a' && str[i] <= 'z')
why are you reinventing the wheel? ctype.h is your friend
Use the toupper(int) method. Something like
char* stoupper(char str[]);
char str[100]= "uppercase";
printf("%s" , stoupper(str)); // Test to make sure it is working
char* stoupper(char str[])
{
int i = 0;
while(str[i])
{
str[i]=toupper(str[i]);
i++;
}
return str;
}
I think your if condition should be:
if(str[i] >= 'a' && str[i] <= 'z')
your condition in if statement needs to be changed
if(str[i] >= 'A' && str[i] <= 'Z')
May I suggest another way to change Uppercase to lowercase and vice-versa
char* stoupper(char str[])
{
for(int i=0;i<strlen(str);i++)
if(!(str[i]>='A'&&str[i]<='Z')){
str[i]=str[i]^' ';
}
return str;
}
this method works because
[ASCII value of a lowercase character] XOR [ASCII value of ' '] =[ASCII value of that same character in UPPERCASE ]

Resources