Copying string:while loop breaks on the first condtion only using C - c

I want to copy a string and want to stop copying either the next character is '\0' or '.'
so I wrote
while((dest[i]=src[i])!='\0'||src[i]=='.');
i++;
when the character is '\0' the while loop works perfectly
but in case of '.'
must I write a separate "if condition" for the second part ?and why?

You have an infinite loop there.
while((dest[i]=src[i])!='\0'||src[i]=='.'); // This is the end of the loop,
// with an empty statement.
Also, you need to change the conditional a little bit.
(dest[i]=src[i]) != '\0' && src[i] != '.'
To avoid the empty statement problem after while and if statements, you can change your coding standard so that you always use the {}.
while ( (dest[i]=src[i]) != '\0' && src[i] != '.' )
{
++i
}

Related

How to read character until a char character?

I'm trying to do a loop that read from a file a single character until it finds '\n' or '*'.
This is the loop that I wrote:
i=0;
do {
fscanf(fin,"%c",&word[i]);
i++;
} while(word[i]!='*'&&word[i]!='\n');
Now I tried to see why it doesn't work with a debugger. When I print word[i] immediately after the fscanf it shows me the correct character but then, if I try to print word[i] while it's doing the comparison with '*' or '\n' it shows me that word[i] is '\000' and the loop never ends.
I also tried with fgetc but I have the same error.
You have to make sure that the character you are processing is the same you just read.
Actually you increment counter i before testing word [i], that's why your check fails.
Try instead
i=0;
do {
fscanf(fin,"%c",&word[i]);
}while(word[i]!='*'&&word[i++]!='\n');
I would rather move the check in the loop (break if the condition is satisfied) leaving in the while check the test on word array length.
Another way:
for(;;) {
int c = fgetc(fin);
if ( c == EOF ) {
break;
word[i] = c;
if( c == '*' || c == '\n' ) {
break;
}
}
Your while condition is not testing the same element of word that you just read, because i++ incremented the variable before the test.
Change the test to use word[i-1] instead of word[i] to adjust for this.
BTW, word[i] = fgetc(fin); is a simpler way to read one character.

C program to read specific lines from a file

I'm trying to make a program that will count the lines in a file and will refer to specific lines as another count(i.e lines that start with a # should not be counted)
while(fgets(tempstring,sizeof(tempstring),fptr)){
lines++;
if(tempstring[0] != '#' || tempstring[0]!='\n'|| tempstring[0]!=' '){
++count;
}
Now what am I doing wrong here?
Also i have noticed that the first time i call fgets i get ∩ as an output for tempstring[0] why is that?
Your condition is always true - you wanted to either use &&, or negate the overall ||:
if (tempstring[0] != '#' && tempstring[0]!='\n' && tempstring[0]!=' ')
or
if(!(tempstring[0] == '#' || tempstring[0] == '\n' || tempstring[0] == ' '))
which is equivalent. Note that you can remove if altogether, because true in C is the same as 1:
count += (tempstring[0] != '#' && tempstring[0]!='\n' && tempstring[0]!=' ');
Also note that fgets may or may not give you the beginning of line, depending on sizeof(tempstring). If tempstring is not long enough for the whole string from the file, your call may produce a string from the middle of another string, causing incorrect behavior. This is harder to fix, because now you need a loop that checks for the last character of the string returned from fgets to be '\n'.

How does this C iteration work?

Sorry if this seems like a stupid question, but I came across this code that transforms a mixed-case string to a lower-case one, I understand it except the string iteration:
for (int i=0; str[i]; i++) {
str[i] = tolower(str[i]);
}
In my understanding the expression str[i] means continue iterating if str[i] exists, is that correct? And does C not check the boundaries of an array which means that the loop code go on forever?
Having the guard as str[i] is the same as str[i] != '\0', whereby the '\0' is the null-terminating character of a string. The guard of for loops either evaluates to true or false, or 0 and 1 in this case. Simply using str[i] checks if the character is valid(true), and not a null-terminating character(false), which marks the end of a string.
If your new to C strings, you can also just use strlen() from <string.h> for your guard. This function just returns the length of the string. Your code would then look like this:
for (int i=0; i < strlen(str); i++) {
str[i] = tolower(str[i]);
}
Although this is valid, using the first approach is much easier to use and more C like.
The condition str[i] tests for the end of the string. C-strings are null-terminated, so when the character '\0' is reached, the loop terminates.
No, C does not check array bounds.
It will not go forever because every string (char*) has to end with '\0'. So it loops until str[i] is not 0.
In C every C-string ie. constant you would type is represented as for example:
string a = {'x', 'y', 'z', 0}
for
a = "xyz"
Therefore, the loop terminates when meets the last character since the last element is NULL (0) which is obviously false.
You are right about the expression meaning "if(str[i])" exists, then continue iterating. However, the loop will NOT go on forever because once the value of "i" becomes greater than or equal to (>=) length of the array "str[]", the condition "if(str[i])" will fail. Thus, the loop will only execute as many times as the number of elements in the "str[]" array.

what is wrong with the while loop here ? C basics

I am trying to count the number of letters of a word before the space. For eg. "Hello how" is my input string and I am trying to count the number of letters in the first word.
#include<stdio.h>
#include<string.h>
int main()
{
char a[30];
int count = 0;
printf("Enter the string.\n"); // Enter hello how as string here.
gets(a);
for ( i = 0; a[i] != '\0'; i++ )
{
while( a[i+1] != ' ' )
count++;
}
printf("%d\n",count);
}
This is a small part of a bigger code, I am actually expecting the value of count to be 5 but it gets into some sort of infinite loop which I am unable to figure out. If I use if instead of while , I get the expected answer. I know gets is not very reliable and I will not use once I get better at programming so it will be kind of you to post your answer about the loop instead of gets. Thank You.
The NUL character is written with a backslash (\), not forward slash (/).
for (i = 0; a[i] != '\0'; i++)
Furthermore, the inner loop will not terminate because you're not incrementing i.
while (a[i] != ' ') {
i++;
count++;
}
Actually, you should not really have two loops. One loop is all you need.
for (i = 0; a[i] != '\0' && a[i] != ' '; i++) {
count++;
}
The expression within the while statement does not depend on count. So with every iteration of the while loop the count gets incremented, but that has no influence on the while conditional, hence it will loop ad infinitum or never, depending on the character at a[i+1].
In addition to that, the conditional statement for the for loop is not written correctly either. The string escape for a NUL character is \0 (backslash). Or you can just compare against a 0 literal, which has exactly the same outcome (though when it comes to the subtleties of C it does not mean exactly the same, but that's splitting hairs).
Use '\0' instead of '/0' in the for loop condition and also the while loop condition will never be false because i remains the same

Dont understand this syntax

Given this loop, why is there a semi colon at the end?
for(s = string; *s == ' '; s++)
;
thanks
edit * so is it possible to reverse this procedure so it starts at the end of a string and checks for a space and decreases until it finds a charachter?
It is an empty statement, which is a no-op in C. It's as if you had said:
for(s = string; *s == ' '; s++)
{
// do nothing
}
You use this when everything can be done in the for( ... ) construct itself - the C grammar requires that there be a controlled statement, but there is nothing for it to do.
The semicolon makes an empty statement in the loop. This loop searches for the first non-blank char in string.
The semicolon means that nothing is done inside the loop. In your code the loop just loops until the character in the string is not a space. That is, after that line s points to the first character in the string that is not a space.
Because in C (and others) for grammar is:
for (init; condition; step)
body
Where body can be a closure ( a block of code in {}), but body can also be a empty with ;
I'd like to point out that the loop could be written like this to make it more explicit what is going on and increase readability:
for(s = string; *s == ' ';)
s++;
Or using a while loop:
s = string;
while(*s == ' ')
s++;
But I think the first approach with the empty body is more "c-idiomatic" (and harder to read).
It causes the loop to do nothing. All that happens is that the pointer is advanced.
There has to be a statement or block as the "body" of the for loop. This is what is executed each time through the loop (as long as s is still pointing to a space).
A semicolon on its own is the empty statement -- that is, nothing happens in the loop body, just the s++ on the for loop line.

Resources