Getline từ file bị mất ký tự đầu tiên

Mọi người giúp em với ạ, em sử dụng getline từ file thì bị mất kí tự đầu ,em tạo 1 string để getline sau đó chạy xòng for để gán lại mảng kí tự thì xuất hiện kí tự rác . Em suy nghĩ từ sáng đến giờ vẫn không ra mong mọi người giúp ạ!

#include <iostream>
#include <mylib.h>
#include <iomanip>
#include <string.h>
#include <fstream>
using namespace std ;
#define MAXLIST 100

const int so_itemp = 8 ; // so yeu cau cua bai toan
const int cot = 20 ;
const int dong=5 ;
const int Up=72 ; // di len 
const int Down=80 ; // di xuong

struct Sinhvien{
	int maso ;
	char ho[31] ;
	char ten[31] ;
};
struct List{
	int n ; // so hoc vien co trong danh sach
	Sinhvien *Node[MAXLIST] ; // Mang con tro  
};


//Set color 
void Normal(){
	SetColor(15) ; // White
	SetBGColor(0) ; // Black
}
// Set color 
void HightLight(){
	SetColor(15) ; //White
	SetBGColor(1); //Blue
}
//Menu
char Thucdon[so_itemp][50]=   {"1.Nhap danh sach hoc vien	 		",
								"2.Liet ke hoc vien       	 		",
								"3.Sap xep danh sach theo ten		",
								"4.Them hv vao danh sach va sap xep ",
								"5.Tim hv bang ma so				",
								"6.Save danh sach hv				",
								"7.Load danh sach hv				",
								"8.Ket thuc (maso <= 0)				"} ;
// Tao mang dong
int MenuDong(char Thucdon[so_itemp][50]){
	system("cls") ;
	int chon=0 ;
	// xuat menu ra
	for(int i=0 ; i<so_itemp ; i++){
		gotoxy(cot, dong+i) ;
		cout<<Thucdon[i] ;
	}
	HightLight() ;
	gotoxy(cot,dong+chon) ;
	cout<<Thucdon[chon] ;
	char kytu ;
	do{
		kytu=getch() ;
		switch(kytu){
		//if(kytu==0) kytu=getch() ;
		case Up: if(chon+1>1){
					Normal() ;
					gotoxy(cot,dong+chon) ;
					cout<<Thucdon[chon] ;
					chon-- ;
					HightLight();
					gotoxy(cot,dong+chon);
					cout<<Thucdon[chon] ;
		}break;
		case Down: if(chon+1<so_itemp){
					Normal() ;
					gotoxy(cot,dong+chon) ;
					cout<<Thucdon[chon] ;
					chon++ ;
					HightLight() ;
					gotoxy(cot,dong+chon);
					cout<<Thucdon[chon];
		}break;
		case 13 : return chon+1 ;
	}	
	}while(true) ;
}
// Tim kiem ma so sinh vien
int Search(List &ds,int x){
	for(int i=0 ; i<ds.n ; i++){
		if(ds.Node[i]->maso==x) return i ;
	}
	return -1 ;
}
// Nhap chuoi
void Nhapchuoi(char *Tieude , char *s){
	cout<<Tieude; 
	do{
		gets(s) ;
	}while(strcmp(s,"")==0);
}
// Nhap danh sach 1 sinh vien
int NhapSV(List &ds, Sinhvien &sv){
	while(1){
		cout<<"Nhap ma so (maso <= 0 ket thuc) ";
		cin >> sv.maso ;
		if(sv.maso<=0) return 0;
		if (Search(ds, sv.maso)>=0){
       		cout<<"Ma so sinh vien bi trung\n";
       		continue;
       	}
       	Nhapchuoi("Nhap ho: ",sv.ho) ;
       	Nhapchuoi("Nhap ten: ",sv.ten) ;
		return 1 ;	
	}
}
// Nhap danh sach sinh vien 
void NhapDSSV(List &ds,int flag){
	Sinhvien sv ;
	// Xoa node khi flag = 0
	if(flag==0){
		while(ds.n>0){
			delete ds.Node[ds.n-1] ;
			ds.n-- ; 
		}
	}
	// Nhap danh sach hoc vien
	while(ds.n<MAXLIST){
		if(NhapSV(ds,sv)==0) return ;
		ds.Node[ds.n]= new Sinhvien ;
		*ds.Node[ds.n] = sv ;
		ds.n++ ;
	}
	if(ds.n==MAXLIST){
		cout<<"Danh sach day\n";
	}
}
// Liet ke danh sach
void Lietkeds(List ds){
	cout<<setw(50) <<"DANH SACH HOC VIEN\n";
	cout<<setw(25)<<"Ma so"<<setw(25)<<"Ho "<<setw(25)<<"Ten\n";
	for(int i=0 ; i<ds.n ; i++){
		cout<<setw(25)<<ds.Node[i]->maso<<setw(25)<<ds.Node[i]->ho<<setw(25)<<ds.Node[i]->ten<<endl ;
	}
}
// Sap xep danh sach theo ten
void SapXep(List &ds){
	Sinhvien temp ;
	for(int i=0 ; i<ds.n-1 ; i++){
		for(int j=i+1 ; j<ds.n ; j++){
			if(strcmp(ds.Node[i]->ten,ds.Node[j]->ten)==1){
				temp = *ds.Node[i] ;
				*ds.Node[i] =*ds.Node[j] ;
				*ds.Node[j] = temp ; 
			}
			else if(strcmp(ds.Node[i]->ten,ds.Node[j]->ten)==0){
				if(strcmp(ds.Node[i]->ho,ds.Node[j]->ho)==1){
					temp = *ds.Node[i] ;
					*ds.Node[i] =*ds.Node[j] ;
					*ds.Node[j] = temp ; 
				}
			}
		}
	}
}
void InsertSinhVien(List &ds,Sinhvien &sv){
	if(NhapSV(ds,sv)==0) return  ;
	int j;
	for(int i=0 ; i<ds.n ; i++){
		if(strcmp(ds.Node[i]->ten,sv.ten)==1)
		{
			j=i ;
			break ;
		}
		else if(i==ds.n-1) j=ds.n ;
	}
	ds.Node[ds.n] = new Sinhvien ;
	for(int i=ds.n ; i>j ; i--){
		*ds.Node[i]=*ds.Node[i-1] ;
	}
	ds.n++ ;	
	*ds.Node[j]=sv ;
}
int InThongTin(List &ds , int x){
	for(int i=0 ; i<ds.n ; i++){
		if(ds.Node[i]->maso==x){
			cout<<"Thong tin sinh vien:\n";
			cout<<ds.Node[i]->maso<<"\t"<<ds.Node[i]->ho<<"\t"<<ds.Node[i]->ten<<endl ;
		}
		break ;
	}
}
// Ghi file
void GhiFile(List &ds,char *Tenfile){
	ofstream FileOut ;
	FileOut.open(Tenfile) ;
	if(FileOut.fail()){
		cout<<"Khong the mo file de ghi\n";
		return ;
	}
	for(int i=0 ; i<ds.n ; i++){
		FileOut <<ds.Node[i]->maso<<" ,"<<ds.Node[i]->ho<<" ,"<<ds.Node[i]->ten<<"\n" ;
	}
	FileOut.close() ; // Dong file
	cout<<"\nDa ghi file thanh cong\n";
}
//Doc du lieu cua 1 sinh vien
void Doc_du_lieu_1_SV(ifstream &FileIn,Sinhvien &sv){
	FileIn>>sv.maso ;
	cout<<"Vi tri chon tro chi vi: "<<FileIn.tellg()<<endl; 
	FileIn.seekg(2 ,ios::cur) ; // dich sang phai 2 byte
	string s1 ;
	getline(FileIn,s1,',') ;
	for(int i=0 ; i<s1.length() ; i++){
		sv.ho[i]=s1[i] ;
	}
	cout<<"s1="<<s1<<endl ;
	cout<<"Sv.ho="<<sv.ho<<endl ;
}
//Xuat file
void DocFile(List &ds ,char* tenfile){
	ifstream FileIn ;
	FileIn.open(tenfile) ;
	if(FileIn.fail()){
		cout<<"Khong the mo file de ghi\n";
		return ;
	}
	while(!FileIn.eof()){
		
	}
}
int main(){
	List ds ;
	ds.n=0 ;
	Sinhvien sv ;
	//MenuDong(Thucdon) ;
	NhapDSSV(ds,0);
	SapXep(ds) ;
	Lietkeds(ds) ;
	GhiFile(ds,"DSSV.txt") ;
	ifstream Filein("DSSV.txt",ios_base::in) ;
	Doc_du_lieu_1_SV(Filein,sv) ;
	return 0 ;
}

Khổ quá nhỉ.
Sao không đọc trực tiếp vào sv.ho mà phải s1for làm gì vậy!

3 Likes

Em thử rồi nhưng không được ạ

Không được là do bạn đọc sai thôi.
Nhất là đoạn dịch 2 byte đấy.

3 Likes

istream là superclass của ifstream :smiley:
seekg không dùng với text mode vì text ko chính xác từng byte.

Ngoài std::getline (string) ra còn có std::istream::getline (char*) bạn.

3 Likes

Cách nhau bởi dấu phẩy phải không?
Bạn dịch 2 byte nhưng dữ liệu dạng kiểu này thì sao?

1234, Họ,...
5678         ,Cũng là họ ,
9876543210	, Vẫn là họ	,...
  1. Dòng 1: liền dấu phẩy.
  2. Dòng 2: nhiều dấu cách.
  3. Dòng 3: kí tự thanh (tab).

Thay cái dịch 2 byte thành getline(FileIn,<biến kiểu string>,',');

3 Likes

Em đã thay thì chạy được rồi , anh giải thích giùm em tại sao không ạ , với lại khi mà getline biến string rồi em chạy vòng for để gán lại cho sv.ho thì nó có giá trị rác còn cách nào khác gán giá trị kiểu string thành mảng kí tự không ạ .

FileIn.getline nó ra char* chuẩn luôn :smiley:

Ra kí tự rác là vì char* đọc tới byte 0 mới hết, ví dụ:
“ASCII”
tức là:

index 0 1 2 3 4 5
"ASCII" A S C I I \0
3 Likes

Anh nói rõ giùm em cái hàm FileIn.getline( tham số của nó là gì ạ ? ) , Hiện tại em đang sử dụng mảng kí tự thì làm sao chuyển từ char* thành char vậy ạ

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?