What is wrong with my special character counter? [duplicate] - c

This question already has answers here:
How to check if variable equal to multiple values
(5 answers)
Closed 3 years ago.
I am reading a string (array of characters in C) from the user, and I am trying to analyze the number of special characters in that string. Special characters are denoted by any character in the ASCII range that is not a vowel or a blank space.
When I use this function, I get different results even when there is no string input from the user.
int restCounter (char string[]) {
int unsigned specialchar = 0;
for (int i = 0; string[i] != '\0'; ++i) {
if(string[i] != ' ' || 'a' || 'e' || 'i' || 'o' || 'u' ||'A' || 'E' || 'I' || 'O' || 'U' || '\0') {
specialchar++;
}
else if(string[i] != 'a') {
specialchar++;
}
else if(string[i] != 'e') {
specialchar++;
}
else if(string[i] != 'i') {
specialchar++;
}
else if(string[i] != 'o') {
specialchar++;
}
else if(string[i] != 'u') {
specialchar++;
}
else if(string[i] != 'A') {
specialchar++;
}
else if(string[i] != 'E') {
specialchar++;
}
else if(string[i] != 'I') {
specialchar++;
}
else if(string[i] != 'O') {
specialchar++;
}
else if(string[i] != 'U') {
specialchar++;
}
else if(string[i] != '\0') {
specialchar++;
}
}
return specialchar;
}

C got a function to do precisely what you want - strchr :
#include <string.h>
unsigned int restCounter (char string[]){
unsigned int specialchar = 0;
for (size_t i = 0; string[i] != '\0'; ++i) {
if( 0 == strchr("aeiouAEIOU ", string[i])) {
++specialchar;
}
return specialchar;
}
Don't roll your own code if there is a standard library function accomplishing what you want.
However, if you don't just want to get the job done but learn by implementing your counting function manually, you got to understand how if works (in most programming languages).
if (s != 1) {
++special;
} else if (s != 2) {
++special;
}
Does not increase special only, if s is not 1 and not 2 at the same time. Just consider what happens if s is 2: the first if condition is true, this the first if body is executed and the else skipped.
Your else statements are superfluous, because they are flawed by this misunderstanding
if you want to increase special only if s is both not 1 and not 2, you need to program it just as you describe it in English:
if( (s != 1) && (s != 2)) {
++special;
}
Thus, if you really want to implement your counting function manually, do it like:
unsigned int restCounter (char string[]){
unsigned int specialchar = 0;
for (size_t i = 0; string[i] != '\0'; ++i) {
char c = string[i];
if (('a' != c) && ('e' != c) && ('A' != c) && ('E' != c)) {
++specialchar;
}
return specialchar;
}
It currently only uses vowels a and e, but I guess you see the pattern how to add i,o,u as well?
be aware, however, that I don't advise this solution: it's is ugly, clumsy, and it's hard to figure out what it does.
Go with the first solution unless you really want to code it manually...
Btw: you won't see a '\0' in the loop body, thus checking the case c == '\0' is unnecessary.

Related

nested for loop to check if first letter of each string in 2d array is a consonant in c

i'm a beginner to programming and I'm running into a problem. I think that this is quite basic but I have looked around everywhere and can't find a solution (probably because of my own lack of understanding). This is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char inputString[999];
char inputArray[99][99];
int a = 0;
int b = 0;
fgets(inputString, sizeof inputString, stdin);
for(int i = 0; i <= (strlen(inputString)); i++) {
if(inputString[i] == ' ' || inputString[i] == '\0') {
inputArray[a][b] = '\0';
a++;
b = 0;
}
else {
inputArray[a][b] = inputString[i];
b++;
}
}
for (int i = 0; i < 99; i++) {
if (inputArray[i][0] == '\0') {
break;
}
for (int j = 0; j < 99; j++) {
iif (inputArray[i][0] == 'a' || inputArray[i][0] == 'e' || inputArray[i][0] == 'i' || inputArray[i][0] == 'o' || inputArray[i][0] == 'u' ||
inputArray[i][0] == 'A' || inputArray[i][0] == 'E' || inputArray[i][0] == 'I' || inputArray[i][0] == 'O' || inputArray[i][0] == 'U') {
if (inputArray[i][j] == '.') {
inputArray[i][j] = '\0';
if (inputArray[i][j] == '\0') {
inputArray[i][j] = 'm';
inputArray[i][j + 1] = 'o';
inputArray[i][j + 2] = 'o';
inputArray[i][j + 3] = '.';
inputArray[i][j + 4] = '\0';
i++;
j = 0;
}
}
else if (inputArray[i][j] == ',') {
inputArray[i][j] = '\0';
if (inputArray[i][j] == '\0') {
inputArray[i][j] = 'm';
inputArray[i][j + 1] = 'o';
inputArray[i][j + 2] = 'o';
inputArray[i][j + 3] = ',';
inputArray[i][j + 4] = '\0';
i++;
j = 0;
}
}
else {
if (inputArray[i][j] == '\0') {
inputArray[i][j] = 'm';
inputArray[i][j + 1] = 'o';
inputArray[i][j + 2] = 'o';
inputArray[i][j + 3] = '\0';
i++;
j = 0;
}
}
}
else if (inputArray[i][0] != 'a' || inputArray[i][0] != 'e' || inputArray[i][0] != 'i' || inputArray[i][0] != 'o' || inputArray[i][0] != 'u' ||
inputArray[i][0] != 'A' || inputArray[i][0] != 'E' || inputArray[i][0] != 'I' || inputArray[i][0] != 'O' || inputArray[i][0] != 'U' || inputArray[i][0] != '\0') {
printf("a");
i++;
j = 0;
}
}
}
for (int i = 0; i < 99; i++) {
printf("%s ", inputArray[i]);
if (inputArray[i][0] == '\0') {
break;
}
}
return 0;
}
Essentially I'm trying to input a string, separate them into words using a 2-D array, and then check if the first letters of each string in that array is a consonant or a vowel.
I'm using printf("a"); to test if my code works, but when i run the program and input something like "yo", this is the output:
yo
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayo
The letter "a" is printed 99 times, which is as many times as the inner for loop is ran, so i'm guessing it has something to do with the fact that the first element of every string in the array is also not a vowel and maybe it's a null character, so I tried adding if (inputArray[i][0] == '\0') { (like in the code), but it still doesn't work.
I'd really appreciate if you guys can help me out
EDIT: I changed the code a bit to make it more readable (thanks Benjamin Maurer!), but essentially what I'm trying to do in the first if statement is add "moo" to the end of a word if it starts with a vowel.
Your code starts normal, but why did you then switch from array notation to this absolute madness in the second loop with pointer dereferences? I'm not even going to try to understand that code, bc. it's unreadable.
According to your description, each of inputArray[i] is a string. So checking if inputArray[i][0] is a consontant/vowel should suffice, no?
#include <ctype.h>
#include <stdio.h>
// ...Read input...
for (int i = 0; i < 99; ++i) {
if (isalpha(inputArray[i][0])) {
char c = toupper(inputArray[i][0]);
switch (c) {
// Intentional fallthroughs
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
puts("is vowel!");
break;
default:
puts("is consonant");
}
}
}
Both isalpha and toupper are from ctype.h.
islapha checks whether the argument is an alphabetic latin character (a letter).

Program keeps printing a zero byte?

I am trying to create a program that removes the vowels from a sentence. However, my program keeps failing because it keeps printing zero byte in the string. Would anyone be able to show me where I am going wrong?
#include <stdio.h>
int remove_all_vowels(int character);
int main(void) {
int character = getchar();
while (character != EOF && character != '\0') {
int new_character = remove_all_vowels(character);
putchar(new_character);
character = getchar();
}
return 0;
}
int remove_all_vowels(int character) {
if (character == 'a' || character == 'e' || character == 'i' || character
== 'o' || character == 'u') {
return 0;
} else {
return character;
}
}
Your issue (outputting null characters) comes from the fact that you unconditionally putchar(3) the result of remove_all_vowels, which returns 0 (null character) when given character is a vowel.
To replace vowels with spaces:
You can simply change return 0; in remove_all_vowels to return ' ';
To completely remove vowels:
I would suggest having a function just to help you check against vowels rather than having it act like a transformation over a char, which is really pythonest.
Example of code:
int is_vowel(int character) {
return (
character == 'a' || character == 'e' || character == 'i'
|| character == 'o' || character == 'u'
);
}
// Then, in your main...
...
if (!is_vowel(character))
putchar(character);
your program works fine here
https://www.onlinegdb.com/online_c_compiler
Can give a screenshot whats the problem of your compiler?
#include <stdio.h>
#include <string.h>
int check_vowel(char);
int main()
{
char s[100], t[100];
int c, d = 0;
printf("Enter a string to delete vowels\n");
gets(s);
for(c = 0; s[c] != '\0'; c++) {
if(check_vowel(s[c]) == 0) { // If not a vowel
t[d] = s[c];
d++;
}
}
t[d] = '\0';
strcpy(s, t); // We are changing initial string. This is optional.
printf("String after deleting vowels: %s\n", s);
return 0;
}
int check_vowel(char ch)
{
if (ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch =='o' || ch=='O' || ch == 'u' || ch == 'U')
return 1;
else
return 0;
}

Array doesn't print the first letter in it [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have an array formed from a text file imported by stdin.
The text file looks like this:
"Name"
"Number"
"Name"
"Number"
...
The entire code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char** argv)
{
//number of arguments
if (argc > 2)
{
fprintf(stderr, "Too many arguments\n");
return 1;
}
//check argument 1
{
if (argc == 2)
{
unsigned i = 0;
while (i < strlen(argv[1]))
{
if ((isdigit(argv[1][i])) == 0)
{
fprintf(stderr, "Enter a number\n");
return 1;
}
i++;
}
}
else
{
fprintf(stderr, "argument\n");
return -1;
}
}
//find \n and separate
int g = 0;
int c = 0;
char buffer[102];
char people[42][102];
char numbers[42][102];
while (fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (g % 2 == 0)
{
strcpy(people[c], buffer);
//printf("%s", people[c]);
}
if (g % 2 == 1)
{
strcpy(numbers[c], buffer);
c++;
}
g++;
}
//convert and remove \n
char conv_people[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (islower(people[i][j]) == 0 && people[i][j] != ' ' && people[i][j] != '.')
{
if (people[i][j] == '\n')
{
conv_people[i][j] = '\0';
}
people[i][j] = conv_people[i][j] + 32;
}
}
}
//covert to numbers
char conv[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (conv_people[i][j] == ' ' || conv_people[i][i] == '.' || conv_people[i][i] == '\n' || conv_people[i][i] == '\0')
{
conv[i][j] = '0';
}
if (conv_people[i][j] == 'a' || conv_people[i][j] == 'b' || conv_people[i][j] == 'c')
{
conv[i][j] = '2';
}
if (conv_people[i][j] == 'd' || conv_people[i][j] == 'e' || conv_people[i][j] == 'f')
{
conv[i][j] = '3';
}
if (conv_people[i][j] == 'g' || conv_people[i][j] == 'h' || conv_people[i][j] == 'i')
{
conv[i][j] = '4';
}
if (conv_people[i][j] == 'j' || conv_people[i][j] == 'k' || conv_people[i][j] == 'l')
{
conv[i][j] = '5';
}
if (conv_people[i][j] == 'm' || conv_people[i][j] == 'n' || conv_people[i][j] == 'o')
{
conv[i][j] = '6';
}
if (conv_people[i][j] == 'p' || conv_people[i][j] == 'q' || conv_people[i][j] == 'r' || conv_people[i][j] == 's')
{
conv[i][j] = '7';
}
if (conv_people[i][j] == 't' || conv_people[i][j] == 'u' || conv_people[i][j] == 'v')
{
conv[i][j] = '8';
}
if (conv_people[i][j] == 'w' || conv_people[i][j] == 'x' || conv_people[i][j] == 'y' || conv_people[i][j] == 'z')
{
conv[i][j] = '9';
}
}
}
//compare
int i = 0;
while (i < c)
{
if (strstr(conv[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
if (strstr(numbers[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
i++;
}
return 0;
}
The program takes a list of people and their phone numbers and searches it using argv[1]
The output always omits the first capital letter in each word
So if the file contains a name like: Barrack Obama
the program returns arrack bama
The numbers and converted names are working fine
I didn't want to post the whole thing because it's extremely ugly.
I've run the code and John is output as Éohn. It likely comes from
people[i][j] = conv_people[i][j] + 32;
because you never set any values in conv_people[i] except a terminator.
If I add this first line in the loop
strcpy(conv_people[i], people[i]);
then is outputs
john
with a lower case initial letter.
Aside: it is safer and convenient to use
people[i][j] = tolower(conv_people[i][j]);
which doesn't even need to be tested to see if an uppercase letter was passed.

C function to remove vowels in a string not working?

Here is my function to remove the vowels in a string;
char *removeVowels(char *inString) {
int count = 0; //to count the non vowel characters
for (int i = 0; inString[i]; i++)
if (inString[i] != 'a' || inString[i] != 'e' || inString[i] != 'u' || inString[i] != 'o' || inString[i] != 'i')
inString[count++] = inString[i]; //if character is not a vowel placed at count++
inString[count] = '\0';
return inString;
}
The problem is that it is returning the original string inputted. Any ideas?
There is a confusion between the || and && operators. You want to test that the character is different from 'a' AND different from 'e' etc.
Here is a modified version:
char *removeVowels(char *inString) {
int count = 0; // index for preserved characters
for (int i = 0; inString[i]; i++) {
if (inString[i] != 'a' && inString[i] != 'e' && inString[i] != 'i'
&& inString[i] != 'o' && inString[i] != 'u') {
inString[count++] = inString[i]; // copy the non-vowel character
}
}
inString[count] = '\0'; // set the null terminator.
return inString;
}
Note however that uppercase vowels are not removed by this function, and whether y should be considered a vowel remains to be decided.
As stated in another comment, you need to use && instead of || to make sure that the character does not match any vowels. It might be easier to create a new string and add non-vowels to that string as you go. Something like:
char *removeVowels(char *inString, int size){
char newString[size];
int count = 0;
for(int i = 0; i < size; i++){
if(inString[i] != 'a' && inString[i] != 'e' && inString[i] != 'i' && inString[i] != 'o' && inString[i] != 'u'){
newString[count] = inString[i];
count++;
}
}
newString[count] = '\0';
return newString;
}

How to split wchar_t array and assign details to variables in C?

wchar_t str[]=L"The results are:\nfilename=test.xml\nusername=Tom/";
wchar_t filename[32];
wchar_t username[32];
I have a wchar_t array contained in str variable.
I want to split str variable and assign details with variables:
filename="test.xml";
username="Tom";
How can I split str variable and put details into the related variables in C? Especially trailing / should be included in username variable.
If the filename/username are always on the same lines, this should work:
short i;
i = 0;
while (str[i])
{
if (str[i] == '\n')
{
line++;
}
if (line == 1 && str[i] == '=')
{ i++;
while (stri[i] && stri[i+1] != '\n')
{
filename[fnlen++] = stri[i];
i++;
}
filename[fnlen] = 0;
}
if (line == 2 && str[i] == '=')
{ i++;
while (stri[i] && stri[i+1] != '\n')
{
username[fnlen++] = stri[i];
i++;
}
username[fnlen] = 0;
break;
}
i++;
}

Resources