Out of bounds with find and replace in C++ - c++

I seem to be running into an odd situation that I do not undersand in C++. When I execute a function that parses and replaces strings (Roman Numerals). I end up going out of bound if the string is not present:
Terminal output:
Mac Shell: CPP/>$ ./Roman2Num
Retrieving input:
------------------
Enter a number: 24
input: XXIV
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string
Abort trap: 6
Mac Shell: CPP/>$ ./Roman2Num
Retrieving input:
------------------
Enter a number: 29
input: XXVIV
Roman: XXIX
Mac Shell: CPP/>$ ./Roman2Num
Retrieving input:
------------------
Enter a number: 1999
input: MDCDLXLVIV
Roman: MDCDLXLIX
Mac Shell: CPP/>$ ./Roman2Num
Retrieving input:
------------------
Enter a number: 1998
input: MDCDLXLVIII
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string
Abort trap: 6
Mac Shell: CPP/>$
Code written:
string Cleanup(string Roman){
int count = 0;
printf("input: %s\n", Roman.c_str());
size_t w = Roman.find("VIV");
Roman.replace(w, std::string("VIV").length(), "IX");
/* size_t x = Roman.find("LIX");
Roman.replace(x, std::string("LIX").length(), "IL");
size_t y = Roman.find("VIV");
Roman.replace(y, std::string("VIV").length(), "IX");
size_t z = Roman.find("VIV");
Roman.replace(z, std::string("VIV").length(), "IX");*/
return Roman;
}
I have been doing some reading here:
http://www.cplusplus.com/reference/string/string/replace/
Does anyone see what I am doing wrong?
Am I making this way harder than it needs to be?

You need to check for and protect against the "Not Found" condition.
size_t w = Roman.find("VIV");
if (w != string::npos) {
Roman.replace(w, string("VIV").length(), "IX");
}

When the string is not found Romand.find() returns string::npos, which equals (std::string::size_type)-1.
See here: http://www.cplusplus.com/reference/string/string/find/

Related

List, Int and Input. Problem: ValueError: invalid literal for int() with base 10: ''

enter image description hereI have struggles with this one:
i become Error when u want to convert in int. Anyone know how can I fix this error?
thnks
I tried :
number = list(map(int, input("Next number: ").split(" ")))
expected: die input number to be added listet, but that doesnt happen

Printing elements of a tuple

I am trying to print the elements of a tuple returned by a function where I am comparing the elements of a vector of addresses to those in a database. The fields are: 32-bit int representing the address, int for prefix matching, string containing ASN, string containing matching address, string containing the original address being queried.
for (auto itr = IPs.begin(); itr != IPs.end(); itr++) {
tuple<int,int,string,string,string> entry = Compare(*itr, database);
string out = get<3>(entry) + "/" + to_string(get<1>(entry)) + " " + get<2>(entry) + " " + get<4>(entry) + "\n";
cout << out;
}
I want each line of the output to look like this:
"{prefix}/{# bits of prefix} {ASN} {address}\n"
However, the output looks like this:
12.105.69.1528 15314
12.125.142.190 6402
57.0.208.2450 6085
208.148.84.30 4293
208.148.84.16 4293
208.152.160.797 5003
192.65.205.2509 5400
194.191.154.806 2686
199.14.71.79 1239
199.14.70.79 1239
The expected output is:
12.105.69.144/28 15314 12.105.69.152
12.125.142.16/30 6402 12.125.142.19
57.0.208.244/30 6085 57.0.208.245
208.148.84.0/30 4293 208.148.84.3
208.148.84.0/24 4293 208.148.84.16
208.152.160.64/27 5003 208.152.160.79
192.65.205.248/29 5400 192.65.205.250
194.191.154.64/26 2686 194.191.154.80
199.14.71.0/24 1239 199.14.71.79
199.14.70.0/24 1239 199.14.70.79
The part that confuses me the most is the fact that when I print each element on separate lines by replacing each separator with line breaks, it prints the elements correctly:
12.105.69.144
28
15314
12.105.69.152
12.125.142.16
30
6402
12.125.142.19
57.0.208.244
30
6085
57.0.208.245
208.148.84.0
30
4293
208.148.84.3
208.148.84.0
24
4293
208.148.84.16
208.152.160.64
27
5003
208.152.160.79
192.65.205.248
29
5400
192.65.205.250
194.191.154.64
26
2686
194.191.154.80
199.14.71.0
24
1239
199.14.71.79
199.14.70.0
24
1239
199.14.70.79
I suppose that I could just write another function that formats the line breaks into the correct format afterwards, but I am curious about what is causing this. Any ideas?
Could you provide a little more code, so it can be debugged to precisely track the problem?
I think tuple and get are used correctly.
I guess the problem is in the content of strings or at least in the string returned by `get<2>(entry).
Here is a little example which shows what might be wrong
std::string aa = "AAAAA\r"; //"\r" is extra character in aa string
std::string bb = "bbb";
std::cout << aa + " " + bb; //output is " bbbA" not "AAAAA bbb"
The problem obviously doesn't occur when each strings is printed separately in each line.
Double check if string returned by get<X> doesn't contain any special characters or contain OSX end of line mixed with Linux or Windows end of line

Python print() and sys.stdout.write() issues

Guys see below code in python 2.7.
I'm having issues with the "print(ciphertext)" and the "sys.stdout.write(ciphertext)" parts of the code
when I run the code the "print(passline) and the "sys.stdout.write(passline)" come out fine i.e. if the file has a line that says "Billz" it will show as is but when I try to output using either function(i.e. sys.stdout.write() and print()) the ciphertext(via the encryptMessage(key, message) method)
the output splits across lines depending on the "myKey" variable (see below for code and example)
*I understand the limitations of the transposition encryption method, but the 'ciphertext' going to a new line before the original line has finished outputting the line from the line it started from
I think the problem is with the encryptMessage() function and how it interacts with the enc() method, i.e. the for ...in... block of the code in particular
Does that make sense?
i think the answer to this can help when
-reading data from files but not overwriting those files
-when trying to code programmes related to logs, password/word lists
-and understand how the for, in and .join works together
i.e. myKey = 1
C:\Users\baawan\Desktop\Cyber Sec\COMP_lang\python>py cypher7.py
would you like to Encrypt(e) or Decrypt(d): e
Enter file name: pass.txt
Enter Key: 1
This is a list of Passwords to be encrypted
This is a list of Passwords to be encrypted
Billz786
Billz786
123456
123456
Milly
Milly
Bilklzcfvcx
Bilklzcfvcx
i.e. myKey = 2
C:\Users\baawan\Desktop\Cyber Sec\COMP_lang\python>py cypher7.py
would you like to Encrypt(e) or Decrypt(d): e
Enter file name: pass.txt
Enter Key: 2
This is a list of Passwords to be encrypted
Ti sals fPswrst eecytdhsi ito asod ob nrpe
Billz786
Blz8
il76
123456
135
246
Milly
Mlyil
Bilklzcfvcx
Bllcvxikzfc
i.e. myKey = 4
C:\Users\baawan\Desktop\Cyber Sec\COMP_lang\python>py cypher7.py
would you like to Encrypt(e) or Decrypt(d): e
Enter file name: pass.txt
Enter Key: 4
This is a list of Passwords to be encrypted
T asfsrtecthi t sdo reisl Pws eyds ioao bnp
Billz786
Bz
i7l8l6
123456
15263
4
Milly
Myi
ll
Bilklzcfvcx
Blvizclcxkf
i.e. myKey = 8
C:\Users\baawan\Desktop\Cyber Sec\COMP_lang\python>py cypher7.py
would you like to Encrypt(e) or Decrypt(d): e
Enter file name: pass.txt
Enter Key: 8
This is a list of Passwords to be encrypted
Tafreth d eilPsedsia n
sstcitsors w y oobp
Billz786
B
illz786
123456
123456
Milly
Milly
Bilklzcfvcx
Bviclxklzcf
the code is
def enc():
myMessage = raw_input('Enter file name: ')
myKey = int(raw_input('Enter Key: '))
text_file = open(myMessage, "r")
lines = text_file.readlines()
for passline in lines:
myMessage = passline
ciphertext = encryptMessage(myKey, myMessage)
print(passline)
#sys.stdout.write(passline)
print ciphertext
#sys.stdout.write(ciphertext)
text_file.close()
def encryptMessage(key, message):
ciphertext = [''] * key
for col in range(key):
pointer = col
while pointer < len(message):
ciphertext[col] += message[pointer]
pointer += key
return ''.join(ciphertext)
When using readlines and most other ways of reading lines in files, python includes the newline character(s) in the line (So, in your case, passline contains (a) newline character(s)). To prevent this, use something like passline = passline.rstrip('\n\r') in the start of your for loop

Reading file character by character in Python

I have a big file called random.txt containing a lot of 1 and 0. I'm trying to read each value using this script:
random_file = open("random.txt", "r")
while True:
char = random_file.read(1)
if not char: break
print char
The problem is that sometimes instead of printing 0or 1 as a char, it prints 010, so it reads three at once.
I'm using Python 2.7.9
The expected output should be a lot of lines containing just a 0 or 1. In the same line there shouldn't be more than one number.
In python, if not 0 evaluates to True since 0 is a False-y value:
>>> not 0 is True
True
What you probably want is:
random_file = open("random.txt", "r")
while True:
char = random_file.read(1)
if char == "": break
print char
This may explain some of your problem. Not sure where the rest of it comes from.

Python 2.7, unexpected EOF while parsing

I am a newbie to Python and I was trying my hand at the following problem: I want to add numbers entered by the user. Here is my program
add = 0
num = input('Enter a number:')
add = add + num
while num != ' ' :
num = input('Next number:')
add = add + num
print add
I want to terminate the program when a blank is entered. So I know the problem is with line 4. What would be the correct syntax?
Thanks in advance for your help
In python 2.7 user input should be processed using raw_input
This is because input is semantically equivalent to:
eval(raw_input(prompt))
which, when given an empty string, will cause the following line of code:
eval('')
will return an EOF error while parsing, since empty is not a valid object to parse.
Since raw_string doesnt parse the string into an int you'll also have to use int() to convert it when you do the addition.
You also need to change to while statement:
add = 0
num = raw_input('Enter a number:')
# you cant do a + here what if the user hits enter right away.
if num:
add = int(num)
while num: # enter will result in a null string not a space
num = raw_input('Next number:')
if num:
add = add + int(num)
print add
Try following and read a bit.
>>> help(input)
>>> help(raw_input)
>>> s=raw_input()
<return right here>
>>> s
''
>>> s=raw_input()
<one space followed by return here>
>>> s
' '
>>>