So my code, no matter what, returns error 405 (once the test that only two spaces are in the request-line is passed). Which makes me believe I have made an error in creating a code to determine that "GET" is in fact the first word. This is all my code leading up to the "check" that the method type is "GET" or any capitalization thereof.
int s;
s=0;
int i=0;
for(int q=0; q<strlen(line); q++)
{
if(line[q] == ' ')
s++;
}
if(s!=2)
{
error(400);
return false;
}
if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T')||
(line[i+3] != ' ' ))
{
error(405);
return false;
}
Any reason this would always return false? I have int i initialized to 0.
Any reason this would always return false?
Reason :
consider the if statement as :
if(expression_1 || expression_2 || expression_3 || expression_4)
//where
//expression_1 is (line[i] != 'g' || line[i] != 'G')
//expression_2 is (line[i] != 'e' || line[i] != 'E')
//expression_3 is (line[i] != 't' || line[i] != 'T')
//expression_4 is (line[i] != ' ')
let's consider line as GET
Now, expression_1 is always evaluated to be true even though line[i] == G because line[i] != 'g' is true. Therefore, (line[i] != 'g' || line[i] != 'G') is true as true || false == true
Now further expressions are not evaluated as || is a lazy operator and it stops evaluation on first true occurrence as true || anything == true
Thus, if block is always entered and false is always returned.
Solution :
Change the if in your code :
if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T') || (line[i+3] != ' ' ))
To the following :
if((line[i] != 'g' && line[i] != 'G') || (line[i+1] != 'e' && line[i+1] != 'E') || (line[i+2] != 't' && line[i+2] != 'T') || (line[i+3] != ' ' ))
Here line[i] != 'g' && line[i] != 'G' gets evaluated to false as true && false == false and further expressions are checked till a true is encountered.
If no true is encountered then if() block is not entered
Further,
As #twalberg has suggested in the comment, it'd be much readable and understandable if you use your if statement as if( !strncasecmp(line, "get ", 3) ) by including the strings.h header file
Know more about strncasemp() function here : click
That comparison makes the code much harder to read. Use the function strncasecmp() (in either string.h or strings.h) instead:
if (strncasecmp(line, "get ", strlen("get ")) != 0) {
// ...
}
This will fix the logic error in that line -- your current comparison will always evaluate true. I would also suggest enabling more compiler warnings, as this is something that any compiler should catch.
Related
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 very new to the C programming language and was curious how would you capitalize a letter in a program following a punctuation mark without using an array. I tried using the ASCII code values by subtracting 32 but it just doesn't seem to work in my code. Here is a portion of my code that outputs the letters. I thought word = word - 32 would work but it does nothing when running the program. I'd appreciate the help!
while ((word = getchar()) != EOF && word != '\n'){
if (word == ' ' || word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&' || word == ';' || word == ':'){
printf("\n");
word = word - 32;
}
if ((word >= 'A' && word <= 'z')){
printf("%c", word);
}
}
You can use a flag to check whether the last entry was a punctuation, and then alter the next input based on the flag and reset it again
char word;int flag=0;
while ((word = getchar()) != EOF && word != '\n'){
if(flag==1){
printf("\n");
word = word - 32; flag=0;
}
if (word == ' ' || word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&' || word == ';' || word == ':'){
flag=1;
}
if ((word >= 'A' && word <= 'z')){
printf("%c", word);
}
}
I've already got the part of my program that echoes user input to work, but my code seems to ignore the while line where I specify not to echo the characters in the array if they are spaces or punctuation. My code is as follows:
#include <stdio.h>
int main()
{
int word = 0, punct = 0;
int i = 0;
char phrase[500];
printf("Enter any phrase.");
while (1)
{
do
{
phrase[i] = getchar(); //gets incoming char and outputs it
putchar(phrase[i]);
} while (phrase[i] != ' ' && phrase[i] != '.' && phrase[i] != '!' && phrase[i] != '#' && phrase[i] != '#' && phrase[i] != '$' && phrase[i] != '%' && phrase[i] != '%' && phrase[i] != '^' && phrase[i] != '&' && phrase[i] != '*' && phrase[i] != '(' && phrase[i] != ')' && phrase[i] != '-' && phrase[i] != '_' && phrase[i] != '=' && phrase[i] != '+' && phrase[i] != '\\' && phrase[i] != '|' && phrase[i] != '{' && phrase[i] != '}' && phrase[i] != '[' && phrase[i] != ']' && phrase[i] != ':' && phrase[i] != ';' && phrase[i] != '\'' && phrase[i] != '\"' && phrase[i] != '<' && phrase[i] != '>' && phrase[i] != ',' && phrase[i] != '?' && phrase[i] != '/'); //prevents punctuation and spaces from bein outputted
printf("\n");
i++;
}
}
When I run the program the user input is all echoed, including the punctuation and spaces, what exactly is wrong and how do I make it so that the code outputs everything char by char and skip over the punctuation and spaces? And how would I keep the loop going after punctuation is skipped?
//gets incoming char and outputs it
This comment says it all. Your do loop outputs the character before the while test checks it. The while only stops when the input character is a punctuation mark, but by that time the character has already been sent. And then the outer while (1) loop causes the whole thing to happen all over again.
The way to fix the issue is to test the character before sending it to output. For example:
while(1) {
phrase[i] = getchar();
if (isPunctuation(phrase[i]) == false) {
putchar(phrase[i]);
}
else {
printf("\n");
i++;
}
}
Note that you don't really want the while (1) since that means the loop will continue forever. After the 500th character, you'll exceed the capacity of the phrase array and start writing into memory that doesn't belong to you. I'll leave it to you to think up a more reasonable loop condition.
I am doing the K&R book.
If i check a == then everything works but if I check !=, then no histogram is printed.
This works
while( (c = getchar()) != EOF )
{
if(c == ' ' || c == '\t' || c =='\n')
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
else
if(state == OUT)
state = IN;
if(state = IN)
++wc;
}
but changing the if section to this does not:
if(c != ' ' || c != '\t' || c !='\n'){
if(state == OUT){
state = IN;
++wc;}
else
++wc;
}
else
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
}
I want every character that is not a tab or a space or a newline. So i wrote c != '\t' || c!= ' ' || c!= '\n'. which i take to mean as
If c is not (!=) space(' ') then its 1(true) OR(||) if c is not (!=) tab('\t') then its 1 OR(||) ...so on.
And if any one of the OR statement is true then the whole statement is true and body should execute, so why isn't it executing?
Thanks for noticing the typo in first snippet, I corrected it, but I want to ask is why doesn't the second snippet work?
Answer:
This works perfectly:
if(c != ' ' && c != '\t' && c !='\n' && c != '"' && c!= '.' && c != ','){
if(state == OUT){
state = IN;
++wc;}
else
++wc;
}
else
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
In the first snippet
if(state = OUT)
...
if(state = IN)
is wrong. Change this to
if(state == OUT)
...
if(state = IN)
After that if your first snippet of code works well then change
if(c != ' ' || c != '\t' || c !='\n')
in your second snippet to
if(c != ' ' && c != '\t' && c !='\n')
if you with to negate the whole if stament try if(!(c == ' ' || c == '\t' || c =='\n')) or its logical equivalent if( c != ' ' && c != '\t' && c == '\n')). Negating the individuals elements is not enough. You have to change the or's to and's.
Every character is either "not a space", "not a tab", or "not a newline". A tab, for instance, is "not a space" and "not a newline". So that if-condition will never be false. It sounds like you want to look for characters which are "not a space" AND "not a tab" AND "not a newline".
I'm trying to work through a book on C and I am stuck on the following error:
while((c = getchar()) != EOF){
if(c >= '0' && c <= '9'){
++ndigit[c-'0'];
}
else if (c == ' ' || c == '\n' || == c =='\t'){
++nwhite;
}
else{
++nother;
}
}
The compiler is complaining about my comparison of var 'c' and the whitespace chars.
error: expected primary-expression before '==' token
I haven't written C since school so I am confused as to what is wrong with my syntax. Thanks.
else if (c == ' ' || c == '\n' || == c =='\t'){
^^
|
+-- This == should be deleted.
You wrote:
else if (c == ' ' || c == '\n' || == c =='\t')
But it should be
else if (c == ' ' || c == '\n' || c =='\t'){
Notice the == before the last part of the conditional that is removed, in the second snippet. Even if you haven't written C in a while, it looks like that was a simple typo rather than a misunderstanding of those operators.
Get rid of the == c on the else if line:
else if (c == ' ' || c == '\n' || == c =='\t'){
Well, that == in
if (c == ' ' || c == '\n' || == c =='\t')
^^ Here
makes no sense whatsoever. Why did you put it in there?
this is your problem " == c =='\t')" get rid of the == to the left of the c variable
The problem is on the line else if (c == ' ' || c == '\n' || == c =='\t'){
It's that == c == '\t' at the end that's throwing it off. C doesn't allow you to string together comparisons and, additionally, there's nothing to the left of the == (that's what it means by "expected primary expression before ==", it wants something to compare to but there's nothing).
It should be else if (c == ' ' || c == '\n' || c =='\t'){