I am trying to take in 10 characters over a serial console and add them to an array called buffer. The first character needs to be 'L' or 'S' and the next characters either '1' or '0'.
The code passes the first if statement ok. But the line if((buffer[0] != 'L') || (buffer[0] != 'S')) doesn't seem to work even when I enter 'L' OR 'S'.
Is there anything wrong with using the buffer[0] != notation?
int main(void)
{
char ch;
char buffer[10] = "";
putstring("Enter 9 characters beginning with 'L' or 'S' and 8 digits\r\n");
for (int i = 0; i < 9; i++) {
ch = getcharacter();
if ((ch == '0') || (ch == '1') || (ch == 'L') || (ch == 'S')) {
buffer[i] = ch;
//check first character
if((buffer[0] != 'L') || (buffer[0] != 'S')) {
printf("First letter must be L or S\r\n");
goto error;
}
error:
return -1;
}
}
}
int getcharacter(void) {
char c = 0;
const uint32_t recieve_ready = 1 << 7;
//disable interrupt for a read ready
*uart_control_reg = 0;
while (1) {
//check if RRDY bit is set
if ((*uart_status_reg) & recieve_ready) {
c = *uart_rxdata_reg;
break;
}
}
return ((char) c);
}
if((buffer[0] != 'L') || (buffer[0] != 'S'))
is wrong, you need
if((buffer[0] != 'L') && (buffer[0] != 'S'))
or
if (!(buffer[0] == 'L' || buffer[0] == 'S'))
Your original code was "if the char is not L or the char is not S" which is always true. If the char is L, then the second part was true, making the whole if statement true.
Just noticed Chris Turner's comment above. The return -1 is always executed, move it to replace the line that says goto error.
Try using
if((buffer[0] != 'L') && (buffer[0] != 'S'))
instead of
if((buffer[0] != 'L') || (buffer[0] != 'S'))
Just some logic problem here. According to your code, the char needs to be equal to 'L' AND 'S' to avoid the condition, which is never the case !
Related
There is a file "poem.txt":
*The ho$use cat sits.*
*And sm%iles and) sing&s.*
*He% know*(s a l_ot*
*Of s!ecret thi<ngs.*
I need to delete unnecessary symbols from it and write it to another file "poem_modified" without using arrays, functions, structures and pointer and only with <stdio.h> library:
I was able to do it so far:
#include <stdio.h>
int main() {
FILE *input;
FILE *output;
input = fopen ("poem.txt", "r");
output = fopen ("poem_modified.txt", "w");
if (input == NULL || output == NULL)
{
printf("Problem! \n");
return 1;
}
char ch ;
while((ch=getc(input)) != EOF)
fprintf(output, "%c", ch);
fclose(input);
fclose(output);
}
Adding conditions while printing the character can help
Suppose, it is required to include a-z and A-X only with spaces and newline char. So conditions can be made such as if the character is between a-z or between A-Z or it is newline or space, the char will be printed. Otherwise not. Any other conditions can be added.
The getc() function return type is an integer. documentation
Correct indentation helps to understand the code.
#include <stdio.h>
int main() {
FILE *input;
FILE *output;
input = fopen ("poem.txt", "r");
output = fopen ("poem_modified.txt", "w");
if (input == NULL || output == NULL)
{
printf("Problem! \n");
return 1;
}
int ch ;
while((ch=getc(input)) != EOF) {
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == ' ' || ch == '\n'){
fprintf(output, "%c", ch);
}
}
fclose(input);
fclose(output);
}
output :
The house cat sits
And smiles and sings
He knows a lot
Of secret things
Portability Concerns
Using the > and < operators on characters is not a portable solution for this in C. For the special case of the digits '0'...'9' you can do this because the C Standard specifies that these characters must be encoded contiguously and in ascending order.
It is unlikely that using comparison operators to check whether a character is alphabetic in the manner (ch >= 'A' && ch <= 'Z') will cause problems on most modern systems, but problems do occur. Certainly it could be a problem on older systems, such as legacy systems installed at institutions many years ago. This is exactly why the functions described in ctype.h should usually be preferred: these can be relied upon to work portably.
Portable Solutions
But if this is not possible more portable solutions than the aforementioned char comparison which relies upon a particular character encoding can be had.
Being unable to use arrays is a severe (and artificial) constraint. Of the two solutions below, the first solution does use an array (keepers) to encode characters which should be written to output. There is another solution following which does not use such an array, and I think that it meets all of OP's requirements, yet the second solution is a bit more awkward and error-prone to write.
Both solutions are more portable than using (ch >= 'A' && ch <= 'Z') methods, and both give the same results:
$ cat poem_modified.txt
The house cat sits
And smiles and sings
He knows a lot
Of secret things
Using an Array
The first solution defines an array keepers which is initialized by a string literal to contain all characters which should be written to output. As characters are read from input, the program checks in keepers to see if the character is present in this list; if so it is written to output, and if not the next character is read from input.
#include <stdio.h>
int main(void) {
// Open input file and check for errors
const char *input_file = "poem.txt";
FILE *input = fopen(input_file, "r");
if (input == NULL) {
fprintf(stderr, "Unable to open file %s for input\n", input_file);
return 1;
}
// Open output file and check for errors
const char *output_file = "poem_modified.txt";
FILE *output = fopen(output_file, "w");
if (output == NULL) {
fprintf(stderr, "Unable to open file %s for output\n", output_file);
fclose(input);
return 1;
}
char keepers[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ \n";
for (int ch = fgetc(input); ch != EOF; ch = fgetc(input)) {
// Is `ch` an alphabetic character?
size_t idx = 0;
char keeper = keepers[idx];
while(keeper != '\0') {
if (ch == keeper) {
putc(ch, output);
break;
}
keeper = keepers[++idx];
}
}
fclose(input);
fclose(output);
return 0;
}
Using Brute Force
The second solution does the same thing as the first, but without the array. Here instead of using an array to hold the list of characters which should be kept, an if statement with a very long conditional expression encodes this information.
#include <stdio.h>
int main(void) {
// Open input file and check for errors
const char *input_file = "poem.txt";
FILE *input = fopen(input_file, "r");
if (input == NULL) {
fprintf(stderr, "Unable to open file %s for input\n", input_file);
return 1;
}
// Open output file and check for errors
const char *output_file = "poem_modified.txt";
FILE *output = fopen(output_file, "w");
if (output == NULL) {
fprintf(stderr, "Unable to open file %s for output\n", output_file);
fclose(input);
return 1;
}
for (int ch = fgetc(input); ch != EOF; ch = fgetc(input)) {
// Is `ch` an alphabetic character, space, or newline?
if (ch == 'a' || ch == 'b' || ch == 'c' || ch == 'd' || ch == 'e'
|| ch == 'f' || ch == 'g' || ch == 'h' || ch == 'i' || ch == 'j'
|| ch == 'k' || ch == 'l' || ch == 'm' || ch == 'n' || ch == 'o'
|| ch == 'p' || ch == 'q' || ch == 'r' || ch == 's' || ch == 't'
|| ch == 'u' || ch == 'v' || ch == 'w' || ch == 'x' || ch == 'y'
|| ch == 'z' || ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D'
|| ch == 'E' || ch == 'F' || ch == 'G' || ch == 'H' || ch == 'I'
|| ch == 'J' || ch == 'K' || ch == 'L' || ch == 'M' || ch == 'N'
|| ch == 'O' || ch == 'P' || ch == 'Q' || ch == 'R' || ch == 'S'
|| ch == 'T' || ch == 'U' || ch == 'V' || ch == 'W' || ch == 'X'
|| ch == 'Y' || ch == 'Z' || ch == ' ' || ch == '\n')
{
putc(ch, output);
}
}
fclose(input);
fclose(output);
return 0;
}
You can use the various functions from ctype.h to check if something belongs to a certain category of symbols. For example isalpha checks if a character is a letter and isspace checks if it's a space or new line character etc. By using these two functions in combination, we can chose to only print characters that are either letters or spaces. Example:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main (void)
{
char input[] = "*The ho$use cat sits.*\n"
"*And sm%iles and) sing&s.*\n"
"*He% know*(s a l_ot*\n"
"*Of s!ecret thi<ngs.*\n";
size_t length = strlen(input);
for(size_t i=0; i<length; i++)
{
if(isalpha(input[i]) || isspace(input[i]))
{
putchar(input[i]);
}
}
}
Apart from the ctype.h functions making the code easier to read, manual checks like ch >= 'A' && ch <= 'Z' are strictly speaking not well-defined or portable. Because C doesn't guarantee that letters are placed adjacently in the symbol table (see for example the EBCDIC, which was a format used in the Jurassic era). Also the ctype.h functions might handle "locale-specific" characters outside the classic 7 bit ASCII.
I'm trying to solve a problem with replacing letters with numbers. The user will enter a string, in case there are letters, I must substitute the corresponding number, and in case there are * # - symbols, I must simply remove them.
However, I am facing an issue. When the user types only a numeric string, the last character of this string is being removed, which cannot happen. This can only happen if there are letters or symbols in the string.
Source
#include <stdio.h>
#include <string.h>
void alterChars(char phrase[])
{
int i, dashes = 0;
for (i = 0; phrase[i] != '\0'; i++)
{
if (phrase[i] == 'A' || phrase[i] == 'B' || phrase[i] == 'C')
{
phrase[i] = '2';
}
if (phrase[i] == 'D' || phrase[i] == 'E' || phrase[i] == 'F')
{
phrase[i] = '3';
}
if (phrase[i] == 'G' || phrase[i] == 'H' || phrase[i] == 'I')
{
phrase[i] = '4';
}
if (phrase[i] == 'J' || phrase[i] == 'K' || phrase[i] == 'L')
{
phrase[i] = '5';
}
if (phrase[i] == 'M' || phrase[i] == 'N' || phrase[i] == 'O')
{
phrase[i] = '6';
}
if (phrase[i] == 'P' || phrase[i] == 'Q' || phrase[i] == 'R' || phrase[i] == 'S')
{
phrase[i] = '7';
}
if (phrase[i] == 'T' || phrase[i] == 'U' || phrase[i] == 'V')
{
phrase[i] = '8';
}
if (phrase[i] == 'W' || phrase[i] == 'X' || phrase[i] == 'Y' || phrase[i] == 'Z')
{
phrase[i] = '9';
}
if (phrase[i] == '*' || phrase[i] == '#' || phrase[i] == '-')
{
dashes++;
}
else if (dashes > 0)
{
phrase[i - dashes] = phrase[i];
}
}
phrase[strlen(phrase)-1] = '\0';
printf("%s\n", phrase);
}
int main()
{
char phrase[300];
while (!feof(stdin))
{
scanf(" %[^\n]s", phrase);
alterChars(phrase);
}
return 0;
}
Any tips will be valuable. You can access the problem to see where the error is occurring. Anyway, it's on the last entry, at number 190. It is being printed 19, but in fact it should be printed 190, because the removal of characters should only occur when there are letters, or symbols.
Examples
Input: 333-PORTO
Output: 33376786
The problem:
Input: 190
Output: 19
With your "generous" scanning, i.e. practically no expected syntax, you can simply loop while scanning is successful.
while (1==scanf(" %299[^\n]", phrase)) alterChars(phrase);
That fixes the problem with your while condition ( see Why is “while ( !feof (file) )” always wrong? ).
Then you want to read each line until either newline or terminator:
for (i = 0; phrase[i] != '\0' && phrase[i] != '\n'; i++)
And you want to force-terminate with respect to the dashes.
phrase[strlen(phrase)-dashes] = '\0';
and you get the desired output - and in only one line.... ;-)
The explanation is, if you always terminate as with 1 dash, then it works for 1 dash, fails by cutting too much for zero dashes and does other unwanted stuff for more than one dash, i.e. repeat the last few characters.
It is after all unrelated to "numeric only".
I have incorporated this good input by chux:
scanf(" %[^\n]s" is bad as it has not width limit and 2) the s is pointless.
I am working on a program that is in multiple parts that build off each other. The first program has to read from a file and write the content split up by spaces to a new file. Program two is supposed to take this words and add pig latin to them based on the rule of whether it starts with a vowel or a consonant and appending some string at the end depending on which it started with. I am able to open the file and read from the contents, but I am having trouble finding and appending the proper rules to print to the new file.
int processingWord = 1; //0 is not in the middle of a word and 1 is in the middle
char c;
int bytes; //Should be holding the position of the pointer in the file
while((bytes = read(fileRead, &c, sizeof(c))) > 0) {
//printf("%c", c);
if(processingWord == 0) {
processingWord = 1;
}
if(processingWord == 1) {
//Figure out if a vowel or not
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
//Increment the first counter
shard1Count++;
}
//Get to the end of the string
if(c == '\n') {
c = 'r';
write(fileWrite, &c, sizeof(c));
c = 'a';
write(fileWrite, &c, sizeof(c));
c = 'y';
write(fileWrite, &c, sizeof(c));
c = '\n';
write(fileWrite, &c, sizeof(c));
processingWord = 0;
}
}
write(fileWrite, &c, sizeof(c));
}
This is where I am trying to find and append the new "ray" string at the end of the word if it starts with a vowel. The text files look like this
It
is
the
Zucca
Gigantopithecus,
or
Great
Pumpkin,
Charlie
Brown.
And output is supposed to look like this in a new file
Itray
isray
hetay
uccaZay
igantopithecusGay,
orray
reatGay
umpkinPay,
harlieCay
rownBay.
EDIT: processsingWord was an idea I had to check if i was at the end of the line before I checked for vowels and what not. But the logic didn't workout and the output was all jibberish.
My current output file looks like this:
Itray
isray
theray
Zuccaray
Gigantopithecus,ray
orray
Greatray
Pumpkin,ray
Charlieray
Brown.ray
ray
Here is an implementation that should work:
void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);
void doStuff(){
int processingWord = 0;
int already_latin = 0;
char c = 0;
char first_letter = 0;
while(read(fileRead, &c, sizeof(c)) > 0) {
if(processingWord == 0) {
processingWord = 1;
if(!startsWithVowel(c)){ //append constants to the end of the word in pig latin *EDIT*
first_letter = c;
continue;//Here we do not fall through and write
}
}
else{
if(isALetter(c)){ //This is the general case of just writing the read character
write(fileWrite, &c, sizeof(c));
}
else if(c != '\n'){ //Here is handling for , and . special characters
if(isALetter(first_letter)){ //we hit a . or , with a vower word, need to add first letter then "ray"
write(fileWrite, &first_letter, sizeof(first_letter));
}
write(fileWrite, "ray", sizeof("ray"));
write(fileWrite, &c, sizeof(c));
already_latin = 1;
}
else if(c == '\n') { //here is the end of the string
if(isALetter(first_letter)){
write(fileWrite, &first_letter, sizeof(first_letter));
}
if(!already_latin){
write(fileWrite, "ray", sizeof("ray"));
}
write(fileWrite, &c, sizeof(c));
processingWord = 0; //reset all the flags for the next word.
first_letter = 0;
already_latin = 0;
}//end of '\n'
}//end of if/else block
}//end of while loop
}//end of function
/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */
int startsWithVowel(char c){
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
return 1;
}
return 0;
}
/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
return 1;
}
return 0;
}
There is still a bunch of unused stuff like the bytes variable, and things could certainly be cleaner, but this should work how you need it to. Try to run it and let me know how it goes, if im still here ill update any bugs tonight
EDIT
Looks like i did it backwards, only swapping vowels (instead of constants). my pig Latin is rusty.
Ok I made a local string to test the parsing online with codechef.com/ide, you can copy and paste this in there to verify. Change the printfs to writes, which mimic the printfs and i think youre good to go:
#include <stdio.h>
#include <string.h>
void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);
char * str = "It\nis\nthe\nZucca\nGigantopithecus,\nor\nGreat\nPumpkin,\nCharlie\nBrown.";
int main(void) {
doStuff();
return 0;
}
void doStuff(){
int processingWord = 0;
char c = 0;
char first_letter = 0;
int already_latin = 0;
//while(read(fileRead, &c, sizeof(c)) > 0) {
while(strlen(str) > 0){ //Made local for testing, no file io here
c = str[0];
str++; //end of local nonsense you wont have to use
if(processingWord == 0) {
processingWord = 1;
if(!startsWithVowel(c)){
first_letter = c;
continue;//Here we don not fall through and write
}
}
if(processingWord == 1) {
if(isALetter(c)){ //This is the general case of just writing the read character
//write(fileWrite, &c, sizeof(c));
printf("%c",c);
//printf(" SHOULD PRINT FIRST LETTER VOWEL HERE ");
}
else if(c != '\n'){ //Here is handling for , and . special characters
if(isALetter(first_letter)){ //we hit a . or , with a vower word, need to add first letter then "ray"
//write(fileWrite, &first_letter, sizeof(first_letter));
printf("%cay%c",first_letter,c);
}
else{
//write(fileWrite, "ray", sizeof("ray"));
//write(fileWrite, &c, sizeof(c));
printf("ray%c", c);
}
already_latin = 1;
}
else if(c == '\n') { //here is the end of the string
if(!already_latin){
if(isALetter(first_letter)){
//write(fileWrite, &first_letter, sizeof(first_letter));
printf("%cay",first_letter);
//printf(" SHOULD PRINT FIRST LETTER CONSTANT HERE ");
}
else{
//write(fileWrite, "ray", sizeof("ray"));
printf("ray");
}
}
//write(fileWrite, &c, sizeof(c));
printf("%c", c);
processingWord = 0;
first_letter = 0;
already_latin = 0;
}//end of '\n'
}//end of if/else block
}//end of while loop
}//end of function
/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */
int startsWithVowel(char c){
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
return 1;
}
return 0;
}
/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
return 1;
}
return 0;
}
OUTPUT:
Itray
isray
hetay
uccaZay
igantopithecusGay,
orray
reatGay
umpkinPay,
harlieCay
rownBay.
for example when I type in a string "Hello", when I press 'a' it should print "There are 2 vowels." Instead, it says there are 0. I'm new to programming and this is the first language I am learning. Help?
/*
Student: Josiah Eleazar T. Regencia
Course: BSIT 1
Subject: SCS 101
Professor: Daniel B. Garcia
Problem definition:
Write a menu program that will count the vowels and consonants in the string
*/
#include <stdio.h> //printf and scanf functions
#include <string.h> //string functions
#include <stdlib.h>
#include <conio.h>
#define PROMPT "Type in a word, a phrase, or a sentence." //instucts the user
/*
Declaring the function for the user's menu
*/
void menu();
/*
Declaration of function needed to count the vowels in the string
*/
int vowel_count(char *stringInput); //declaring the function to count the vowels sounds
/*
Declaration of function needed to count the consonants in the stringn
*/
int consonant_count(char *stringInput); //declaring the functions to count the consonant sounds
/*
Declaring the function needed to convert the streeting to uppercase
*/
int uppercase(char *stringInput);
/*
Declaring the function needed to convert the streeting to uppercase
*/
int lowercase(char *stringInput);
int main () {
char userInput[100]; // the string the user inputs
char commandKey[1]; //this key is for the menu
char newInput[100]; //this is for the new input to user will put in
int stringLength; //to identify the length of the string
/*
Variables for counting the vowels and consonants
*/
int consonantCount;
printf("%s\n\n", PROMPT); //instucts the user
gets(userInput);
stringLength = strlen(userInput); //gets the length of the string
//fgets(userInput, 100, stdin);
/*if(stringLength > 0 && userInput[stringLength - 1] == '\n') {
userInput[stringLength - 1] ='\0';
}*/
menu(); //prints out the menu for the user to pick his options
/*
The loop will run what the user asks the program to run while at the same time also asking
what the programmer wants next
*/
while(*commandKey != 'X' || *commandKey != 'x') {
//int commandLength; //length of the command key
printf("Enter your menu selection: ");
gets(commandKey);
/*commandLength = strlen(commandKey);
fgets(commandKey, 100, stdin);
if(commandLength > 0 && commandKey[commandLength - 1] == '\n') {
commandKey[commandLength - 1] ='\0';
}*/
if(*commandKey == 'A' || *commandKey == 'a') {
int vowelCount;
vowelCount = vowel_count(userInput);
printf("There are %d vowels.\n\n", vowelCount);
}
if(*commandKey == 'B' || *commandKey == 'b') {
consonantCount = consonant_count(userInput);
printf("There are %d consonants.\n\n", consonantCount);
}
if(*commandKey == 'C' || *commandKey == 'c') {
/*
This condition simply converts the input string to all lowercase letters
*/
lowercase(userInput);
}
if(*commandKey == 'D' || *commandKey == 'd') {
/*
This condition simply converts the input string to all lowercase letters
*/
uppercase(userInput);
}
if(*commandKey == 'E' || *commandKey == 'e') {
/*
Prints the current string
if the string was converted in lowercase letters, the outcome would be all lowercase letters
if the string was converted in uppercase letters, the outcome would be all uppercase letters
*/
printf("%s\n\n", userInput);
}
if(*commandKey == 'F' || *commandKey == 'f') {
/*
When the user wants to test a new string, this is the condition for the user
to automatically ask of it
*/
printf("%s\n", PROMPT);
gets(newInput);
strcpy(userInput, newInput);
}
if(*commandKey == 'M' || *commandKey =='m') {
/*
In case the user forgets, this will serve as a reminder of the menu
*/
menu();
}
if(*commandKey == 'X' || *commandKey == 'x') {
printf("Goodbye!\n");
break;
}
}
}
//Function that displays the menu.
void menu() {
/*
These are the set of command keys given to the user
*/
printf("\n\n\n");
printf("PRESS:\n\n");
printf(" A - Count the number of vowels in the string.\n");
printf(" B - Count the number of consonants in the string.\n");
printf(" C - Convert the string to uppercase.\n");
printf(" D - Convert the string to lowecase.\n");
printf(" E - Display the current string.\n");
printf(" F - Enter another string.\n");
printf("\n");
printf(" M - Display this menu.\n");
printf(" X - Exit the program.\n");
printf("\n\n");
}
/*
Defining the function for the vowel counting
*/
int vowel_count(char *stringInput) {
if ( *stringInput == '\0')
return 0;
else
return vowel_count(stringInput + 1) + (*stringInput == 'a' || *stringInput == 'A')
+ (*stringInput == 'e' || *stringInput == 'E')
+ (*stringInput == 'i' || *stringInput == 'I')
+ (*stringInput == 'o' || *stringInput == 'O')
+ (*stringInput == 'u' || *stringInput == 'U');
}
/*
Defining the function for the vowel counting
*/
int consonant_count(char *stringInput) {
if (*stringInput == '\0')
return 0;
else
return consonant_count(stringInput + 1) + (*stringInput == 'b' || *stringInput == 'B')
+ (*stringInput == 'c' || *stringInput == 'C')
+ (*stringInput == 'd' || *stringInput == 'D')
+ (*stringInput == 'f' || *stringInput == 'F')
+ (*stringInput == 'g' || *stringInput == 'G')
+ (*stringInput == 'h' || *stringInput == 'H')
+ (*stringInput == 'j' || *stringInput == 'J')
+ (*stringInput == 'k' || *stringInput == 'K')
+ (*stringInput == 'l' || *stringInput == 'L')
+ (*stringInput == 'm' || *stringInput == 'M')
+ (*stringInput == 'n' || *stringInput == 'N')
+ (*stringInput == 'p' || *stringInput == 'P')
+ (*stringInput == 'q' || *stringInput == 'Q')
+ (*stringInput == 'r' || *stringInput == 'R')
+ (*stringInput == 's' || *stringInput == 'S')
+ (*stringInput == 't' || *stringInput == 'T')
+ (*stringInput == 'v' || *stringInput == 'V')
+ (*stringInput == 'w' || *stringInput == 'W')
+ (*stringInput == 'x' || *stringInput == 'X')
+ (*stringInput == 'y' || *stringInput == 'Y')
+ (*stringInput == 'z' || *stringInput == 'Z');
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int uppercase(char *stringInput) {
while(*stringInput) {
*stringInput = toupper(*stringInput);
stringInput++;
}
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int lowercase(char *stringInput) {
while(*stringInput) {
*stringInput = tolower(*stringInput);
stringInput++;
}
}
This loop will never stop:
while(*commandKey != 'X' || *commandKey != 'x')
A loop stops when its condition is false. For *commandKey != 'X' || *commandKey != 'x' to be false, it is logically equivalent for *commandKey == 'X' && *commandKey == 'x' to be true, which doesn't quite work. *commandKey can't be both 'X' and 'x'.
Instead, you want:
while(*commandKey != 'X' && *commandKey != 'x')
Which will stop when *commandKey is 'X' or 'x'.
Also, you never initialized commandKey, so you can't test it in the loop (using values of uninitialized variables is undefined behavior). And if you want to treat it as a string, you need to declare it such that it holds at least 2 characters, because the null character is needed:
char commandKey[2] = { 0 };
This will initialize commandKey to an empty string. Remember that gets() will null-terminate the string, so, even if your command is just one key, gets() will need at least 2 positions to fill - the character command and the null terminating byte. Alternatively, you can leave commandKey as is (provided that you initialize it), and use getchar() instead, which reads one single character.
Write a program that reads input up to # and reports the number of times that the sequence ei occurs.
I have little confusion with sequence such as 'ieei' where compiler does enter 3rd 'e' but never fetches 'i' with getchar(), why and if someone can improve this before myself it'd be good?
char ch;
int sq=0;
while ((ch = getchar()) != '#')
{
if (ch == 'e')
{
ch = getchar();
if (ch == 'e')
ch = getchar();
if (ch == 'i')
sq++;
}
}
printf("Sequence occurs %d %s\n", sq, sq == 1 ? "time" : "times");
In my opinion it's simplest to keep the result of the last getchar() in a variable rather than have an extra getchar() inside your loop.
char ch;
int sq=0;
char lastCh = ' ';
while((ch=getChar())!='#') {
if(lastCh=='e' && ch=='i')
sq++;
lastCh=ch;
}
This gives the correct result no matter how many e's in a row or whatever, and breaks at the first # character.
I'm tempted to implement it as:
char ch=0;
int sq=0;
do{
if( (ch=( ch=='e'? ch:getchar() )) == 'e' && (ch=getchar()) == 'i' )
++sq;
}while(ch!='#');
But it uses ?: and && for control flow, which might be confusing especially to beginners.
On second thought it's not that hard to unroll it:
char ch=0;
int sq=0;
do{
if( ch!='e' ) ch = getchar();
if( ch == 'e' ){
ch = getchar();
if( ch == 'i' ) ++sq;
}
}while(ch!='#');