2010-05-01 7 views
1

문자열 배열 인 "name"을 포함하는 파일을 만들 필요가 있습니다. char 배열 및 char 배열 - "data"- C++에서 char 배열 -하지만 첫 번째 내가 직면 한 문제는 "데이터"에서 "이름"을 분리하는 방법입니다. 개행 문자는이 경우 작동 할 수 있습니다 (이름에 "\ n"이 없다고 가정). 그러나 "데이터"부분에 특수 문자를 사용할 수 있으므로 끝나는 시점을 알 수 없습니다. "데이터"크기의 데이터 앞에있는 파일의 int 값! 나는 다음과 같은 코드로이 작업을 수행하려고 :C++에서 이진 파일 읽기 및 쓰기

if((fp = fopen("file.bin","wb")) == NULL) 
{ 
    return false; 
} 
char buffer[] = "first data\n"; 
fwrite(buffer ,1,sizeof(buffer),fp); 
int number[1]; 
number[0]=10; 
fwrite(number ,1,1, fp); 
char data[] = "1234567890"; 
fwrite(data , 1, number[0], fp); 
fclose(fp); 

하지만 "INT"부분이 바로 있었다면 나는 몰랐다, 그래서 나는이 일을 포함하여 많은 다른 코드 시도 :

char buffer[] = "first data\n"; 
fwrite(buffer ,1,sizeof(buffer),fp); 
int size=10; 
fwrite(&size ,sizeof size,1, fp); 
char data[] = "1234567890"; 
fwrite(data , 1, number[0], fp); 

을 정수를 보는 대신 파일을 열 때 파일에 4 개의 "NULL"문자가 표시됩니다. 그게 정상인가요? 내가 직면 한 다른 문제는 파일에서 다시 읽는 것입니다! 내가 읽으려고 한 코드가 전혀 작동하지 않았다. ("fread"로 시도했지만, "fseek"를 사용해야하는지, 아니면 다른 문자를 읽었는지 확실하지 않다.

나는 다음 다음 쓰고 다시 읽어와 같은 클래스 사용의 생각 :

class Sign 
{ 
public: 
char* name; 
int size; 
char* data; 
}; 

을하지만 C++에서 쉬운 일이 아니었다!

나는 또한 다음과 같은 시도 :

void saveData(char* filename) { 

    fstream filestr; 
    int n; 
    n=10; 
    char* data= "1234567890"; 

    filestr.open (filename, fstream::out | fstream::binary); 
    for (int j = 0; j<5 ; j++) 
    { 
     filestr << n; 

     for (int i = 0; i < n; i++) { 
      filestr << data[i]; 
     } 
    } 
    filestr.close(); 
} 

void readData(char* filename) { 
    fstream filestr; 
    int n =0; 

    filestr.open (filename, fstream::in | fstream::binary); 
    int m =0; 
    //while(!filestr.eof()) 
    while(m<5) 
    { 
     filestr >> n; 

     char *data = new char[n]; 
     for (int i = 0; i < n; i++) { 
      filestr >> data[i]; 
     } 
     printf("data is %s\n",data); 
     m++; 
    } 
    filestr.close(); 
} 

하지만 읽음 ing도 작동하지 않았다.

나는 이상한 인물이 나타납니다.


지금까지 나를 위해 작동 코드는 이것이다 :

void saveData(char* filename) { 
    fstream filestr; 
    char * name = "first data\n"; 
    int n; 
    n=10; 
    char* data= "asdfghjkl;"; 

    filestr.open (filename, fstream::out | fstream::binary); 
    for (int j = 0; j<5 ; j++) 
    { 
     filestr << name; 
     filestr << strlen(data); 
     filestr << data; 
    } 
    filestr.close(); 
} 


void readData(char* filename) { 
    fstream filestr; 
    int n =0; 

    filestr.open (filename, fstream::in | fstream::binary); 
    while(!filestr.eof()) 
    { 
     string name; 
     getline(filestr,name,'\n'); 
     printf("name is %s\n",name.c_str()); 

     filestr >> n; 

     char *data = new char[n]; 
     for (int i = 0; i < n; i++) { 
      filestr >> data[i]; 
     } 
     printf("n is%d\ndata is %s\n",n,data); 
    } 
    filestr.close(); 
} 

하지만 읽기에 문제가 있습니다 :

1- (나는 그것이 진짜 문제는 생각하지 않습니다)를 실제 데이터 외에 다른 문자를 인쇄합니다. 2 - readData에 대한 함수 번만 쓰는 동안 나는 마지막 필드에서 모든 필드를 빈 필드로 가져옵니다. 왜 그 사람이 누군지 압니까? 그것은 while(!filestr.eof())과 관련이 있습니까? 도움을

덕분에

+0

난 그냥 쓴 적이되어, readData 기능을 사용하여 데이터를 읽을 시도를하지만 코드가 ASDFGHJKL입니다 "로의 printf의 출력을 가지고, ²²²²▌▌1US을 \ ♀ + "데이터가 char * data ="asdfghjkl; "일 때 누구나 그 이유를 알 수 있습니까? – Reem

답변

0

음, 코드와 몇 가지 문제가 :

fwrite(buffer ,1,sizeof(buffer),fp); 

기능이 다음과 같이 정의된다

size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream); 

그래서 당신은 버퍼에 정보를 보내는 , 그것은 1의 크기와 sizeof (버퍼)의 개수를 가지고 있다고 말합니다. 그것은 어떤 것들을 위해 일할 수도 있지만, 일반적으로 거꾸로입니다. 사용해보십시오 :

독립적 인 두 문자 폭을 그리고 당신이에 대해 걱정할 필요가없는 상수 값이 없습니다
fwrite(buffer, sizeof(char), strlen(buffer), fp); 

(이것은 기본적으로 모든 문자열에 대해 작동합니다).당신이 그것을 변경 한 후 fwrite에 오류가 발생하면

int number; 

는,이 호출을 사용 :이의

또 다른 사소한 것 : 당신 만하면 사용할 수 있도록

int number[1]; 

당신은 하나의 정수를 :

fwrite(&number, sizeof(int), 1, fp); 

이는 하나의 정수 값을 파일에 씁니다.

코드를 수정 한 후 코드 작동 여부를 확인하십시오. 수정 된 전화로 문제를 해결하는 것이 더 쉬울 것입니다. :)

또한 필드 길이 (파일에 정수로 쓰여 있음)를 사용할 계획이라면 길이와 데이터를 읽는 일종의 시스템을 설정해야합니다. 각 필드의 길이가 아마도 있습니다. 클래스를 사용하는 것은 확실히 그것을 처리하는 가장 쉬운 방법입니다.

편집 : 클래스 대신 구조체 및 함수를 사용하거나 메서드가있는 클래스를 사용할 수 있습니다. 별로 중요하지 않습니다. 둘 다 꽤 간단합니다. 구조체/FUNC :

struct Record 
{ 
    std::string name, data; 
}; 

void writeRecord(Record thisRecord, std::string filename, size_t offset) 
{ 
    if ((fp = fopen(filename.c_str(), "wb")) == NULL) { return NULL; } 

    fwrite(thisRecord.size(), sizeof(unsigned int), 1, fp); // assuming size() return uint 
    fwrite(thisRecord.name.c_str(), sizeof(char), name.size(), fp); 

    // repeat for data or other fields 
    fclose(fp); 
} 
+0

strlen (버퍼)과 sizeof (버퍼)의 차이점은 무엇입니까? intger의 경우 "NULL" "NULL" "NULL"이 표시됩니다. 이 경우 수업을 사용하는 방법을 알려주십시오. 나는 그것을 시도했지만 작동하지 않았고, 내가 한 것보다 조금 더 복잡하다고 생각한다. ( – Reem

+2

Strlen (버퍼)는 버퍼의 문자 수를 계산할 것이다 (예 : "aaa"는 3을 리턴한다.) Sizeof 버퍼)는 버퍼의 바이트 수를 반환합니다. 유니 코드를 사용하는 경우 한 문자는 2 바이트가 될 수 있으므로 차이가 커집니다. 정수는 거대한 숫자가 아니라면 1 또는 2 파일에서 숫자 32는 0x00 0x00 0x00 0x20으로 쓸 것입니다. – ssube

3

먼저 쓰기/바이너리 형식으로 읽는 것은 (이 판독 순서 후에 10 포함됩니다 여기 read_num)과 같이 작동합니다.

FILE* fp = fopen("file.bin", "wb"); 
    int num = 10; 
    fwrite(&num, sizeof(int), 1, fp); 
    fclose(fp); 

    FILE* fp2 = fopen("file.bin", "rb"); 
    int read_num; 
    fread(&read_num, sizeof(int), 1, fp2); 
    fclose(fp2); 

또한이 기록 방법은 C++ 방식이 아니라 C 방식입니다. 파일 작업의 C++ 방법은 스트림, 다음 샘플 참조 의미

#include <fstream> 
#include <string> 

struct data_structure { 
    std::string name; 
    std::string description; 
    int number; 

    void save(const std::string& filename) { 
     std::ofstream file(filename.c_str()); 
     file << name.c_str() << std::endl 
      << description.c_str() << std::endl 
      << number; 
    } 
    void load(const std::string& filename) { 
     std::ifstream file(filename.c_str()); 

     getline(file, name); 
     getline(file, description); 
     file >> number; 
    } 
}; 

int main() { 
    data_structure d, loaded_d; 
    d.name = "Name"; 
    d.description = "Description"; 
    d.number = 5; 

    d.save("file.out"); 
    loaded_d.load("file.out"); 

    return 0; 
} 
+0

첫 번째 부분을 보내 주셔서 감사합니다 .두 번째 부분은 설명이 한 줄 이상이고 줄 바꿈이 포함될 수 있습니다. 내부 캐릭터! – Reem