Reputation: 11
I'm currently taking a class where we are learning Rust. I am running into a really weird issue and I'm not sure what is causing it.
So I have two vectors, and I'm looping through them to print their contents.
when I do the following, it prints out fine,
for index in 0..=delimited_record.capacity()-1{
let cell = delimited_record.get(index).unwrap();
println!("{}",cell);
}
the result is as follows
99
87.4
76
mike
73
95.5
100
gary
however, the following small change makes the 0th index of the second vector come out blank
for index in 0..=delimited_record.capacity()-1{
let cell = delimited_record.get(index).unwrap();
print!("{}",cell);
println!(" - {}",index);
}
the result is as follows
99 - 0
87.4 - 1
76 - 2
mike - 3
- 0
95.5 - 1
100 - 2
gary - 3
The thing is, if I try to do anything besides do a regular print, it'll come back blank. These values are all strings, so what I'm trying to do is convert these values into floats (not the names, just the numbers), but it keeps crashing whenever I try to parse the second array at the 0th index, and it seems it's because its blank for some reason.
Does anyone know what is causing this?
Edit
Here is the code in its entirety, Theres a lot of stuff commented out since i was trying to find out was was causing the issue
use std::{fs, ptr::null};
fn main() {
println!("Hello, world!");
println!("TEST");
let sg = StudentGrades{
name: String::from("mike"),
grades: vec![100.0,80.0,55.0,33.9,77.0]
//grades: vec!['A','B','C','A']
};
let mut cg = CourseGrades{
student_records: Vec::new()
};
cg.from_file("texttest.txt".to_owned());
}
struct StudentGrades{
name: String,
grades: Vec<f32>
}
impl StudentGrades{
fn average(&self)-> f32 {
let mut sum = 0.0;
for grade in self.grades.iter(){
sum += grade;
}
return sum / self.grades.capacity() as f32;
}
fn grade(&self) -> char {
let score = self.average();
let scure_truncated = score as i64 / 1;
match scure_truncated{
0..=59=> return 'F',
60..=69=> return 'D',
70..=79=> return 'C',
80..=89=> return 'B',
_=> return 'A',
}
}
}
struct CourseGrades{
student_records: Vec<StudentGrades>
}
impl CourseGrades{
fn from_file(&mut self, file_path:String){
let mut contents = fs::read_to_string(file_path)
.expect("Should have been able to read the file");
contents = contents.replace(" ","");
let student_rows: Vec<&str> = contents.rsplit('\n').collect();
for student_record in student_rows.iter(){
let mut student_grades:Vec<f32> = Vec::new();
let delimited_record: Vec<&str> = student_record.rsplit(",").collect();
//println!("{}",delimited_record.get(0).unwrap());
//delimited_record.iter().for_each(|x| println!("{}",x));
for index in 0..=delimited_record.len()-1{
//println!("{}",delimited_record.get(index).unwrap().parse::<f32>().unwrap_or_default());
//println!("{}",delimited_record.get(0).unwrap().parse::<i32>().unwrap_or_default());
//student_grades.push(delimited_record.get(index).unwrap().parse::<f32>().unwrap());
let cell = delimited_record.get(index).unwrap();
print!("{}",cell);
println!(" - {}",index);
//println!(" - {}", index < delimited_record.capacity()-1);
if index < delimited_record.len(){
//let grade = cell.parse::<f32>().unwrap();
//student_grades.push(cell.parse::<f32>().unwrap());
//student_grades.push(delimited_record.get(index).unwrap().parse::<f32>().unwrap());
}
else{
/*self.student_records.push(StudentGrades{
name:cell.parse::<String>().unwrap(),
grades:student_grades.to_owned()
});*/
}
}
}
}
}
the testtext.txt file is in the root of the project folder and is just a text file with the following contents
gary, 100, 95.5, 73
mike, 76, 87.4, 99
if I embed it directly, it works just fine, which makes me think there may be something weird when it reads the file
Upvotes: 1
Views: 194
Reputation: 225281
Your file has CR LF (\r\n
, Windows-style) line endings, but you’re only splitting on \n
. Your grade ends up ending with a CR. This is invisible when you println!
it on its own (since the result is CR LF), but if you print something after it on the same line, the CR has returned the cursor to the start of the line and the second thing being printed will write over it.
7 73 73 73 73
^ ^ ^ ^ 9
^ ^
----------------------------------------
'7' '3' '\r' '\n' '9' …
7 73 73 3 -
^ ^ ^ ^ ^ ^
----------------------------------------
'7' '3' '\r' ' ' '-' …
One way to fix this is to strip all whitespace from every cell, including CR:
let cell = delimited_record.get(index).unwrap().trim();
And for debugging, consider formatting with "{:?}"
instead of "{}"
, which will show a literal with invisible characters escaped instead of writing out whatever the string contains directly.
Upvotes: 5