I came across this strange loop behaviour in C. Here is the code:
char arr[SIZE];
fgets(arr, SIZE, stdin);
char brr[SIZE];
int i;
for(i=0; arr[i] != '\0'; i ){
if(arr[i] != ' ') brr[i] = (arr[i] shift - 'a')& 'a';
else brr[i] = ' ';
}
brr[i-1] = '\0';
The code is for Caesar cipher. It takes some text from the user and stores it in arr
, then encodes it by shifting the characters, and this encoded version is put in brr
. So, if user enters 'car' and shift is 2, brr is 'ect'.
The problem is in the last line. Normally, it should be brr[i] = '\0'
, but for some reason the loop will increase I once more after the condition is wrong. I have tried different combinations and it seems like the problem is somehow related to fgets.
Also, the problem is not specific to for loop, while behaves exactly the same.
Edit: Thanks for all the answers. I see now that I should have taken '\n' into account.
CodePudding user response:
somehow related to fgets.
Always test the return values of input functions.
// fgets(arr, SIZE, stdin);
if (fgets(arr, SIZE, stdin)) {
// process arr[]
...
if user enters 'car' and shift is 2,
This is unlikely to only typed 'car'
(3 characters). Certainly the user typed c a r Enter (4 characters) which filled arr[SIZE]
with "car\n"
.
Rather than encode the 4 characters with if(arr[i] != ' ')
, test if arr[i]
is a letter. Research isalpha()
.
Code could exit the for()
loop early if '\n'
is detected.
// for(i=0; arr[i] != '\0'; i ){
for(i=0; arr[i] != '\0' && arr[i] != '\n'; i ){
...
}
// brr[i-1] = '\0';
brr[i] = '\0';
Advanced
brr[i-1] = '\0';
is certainly a problem if i==0
, possible if the first character read is a null character.