Michael Cuevas
Michael Cuevas

Reputation: 11

0th index value in Vector is blank, but only the 0th index of a second vector

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

Answers (1)

Ry-
Ry-

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

Related Questions