Having a problem with the offset character

I am reading a text file. I read the file and change the characters based on the offset specified by the user. Although this works for some characters, it is not for others going beyond a certain point.

My file contains this text: "This is crazy." When I run my code at offset 20, this is what I get: β–’bcβ–’ cβ–’ wβ–’uβ–’β–’

string Security::EncWordUsingRot(int rotNum, string word) { rotNum = rotNum%26; string encWord = word; for (int i = 0; i < word.size(); i++) { char c = word[i]; c = tolower(c); if ((c < 'a') || (c > 'z')) encWord[i] = c; else { c = (c + rotNum); if (c > 'z') c = (c - 26); } encWord[i] = c; } return encWord; } 

* EDIT ** I changed the commented sections to fix my mistake. I changed unsigned char c = word[i] to char c = word[i] . I also added two more lines of code that made sure c was lower than "a". I did this because I noticed a problem when I wanted to essentially return the encrypted operator to its original form.

 string Security::EncWordUsingRot(int rotNum, string word) { rotNum = rotNum%26; string encWord = word; for (int i = 0; i < word.size(); i++) { char c = word[i]; //removed unsigned c = tolower(c); if ((c < 'a') || (c > 'z')) encWord[i] = c; else { c = (c + rotNum); if (c > 'z') c = (c - 26); if (c < 'a') //but I added this if statement if the value of c is less than 'a' c = (c + 26); } encWord[i] = c; } return encWord; } 
+4
source share
2 answers

Edit:

  char c = word[i]; 

To:

  unsigned char c = word[i]; 
+3
source

In C and C ++, you should always pay attention to numerical overflow, because the assumption of the language is that the programmer will never make such an error.

A char is a kind of integer and often 8 bits and signed, which gives an acceptable range of -128 ... 127. This means that when storing a value in a char variable, you should never exceed these limits.

char also a "storage type" meaning that calculations are never performed using char and, for example,

 char a = 'z'; // numeric value is 122 in ASCII int x = a + 20; // 122 + 20 = 142 

x will actually get the value 142, because the calculation is not "overflowing" (all char values ​​are first converted to integers in the expression)

However, storing the value is greater than the allowable range in the variable undefined behavior and code, for example

 char a = 'z'; // numeric value is 122 in ASCII char x = a + 20; // 122 + 20 = 142 (too big, won't fit) 

unacceptable: the calculation is fine, but the result does not fit into x .

Storing a value outside the acceptable range for signed characters in a signed char variable is exactly what your code did and what caused the strange observable behavior. A simple solution is to use an integer to store intermediate results instead of char.

A few more notes:

  • Several character functions do handle integers because they must be able to handle the special EOF value in addition to all valid characters. For example, fgetc returns int and isspace accepts int (they return / accept either char code converted to unsigned or EOF ).
  • char can be signed or not depending on the compiler / options; if unsigned and 8-bit wide, the valid range is 0 ... 255
  • Most often, when you save the value of the external boundaries in a variable, you simply get a β€œwrapping” of behavior, but this is not guaranteed and does not always happen. For example, the compiler is allowed to optimize (char(x + 20) < char(y + 20)) to (x < y) , since the assumption is that the programmer will never overflow with signed numerical values.
0
source

All Articles