我的数据是放在了一组文本中,现在我要从这些文本文件中读取数据,然后生成一维数组。文本的格式如下:
001.txt:
11
13
0
5
6
400
......
数据量很大,大概是2000,000左右。
=======================================================================================
我想到了两个方法,第一个,用BYTE* ptr,指针指向首地址,但是我对指针是在是不明白,我的语句如下
int temp;
fp=fopen("*.txt","r");//(这里的*.txt)只不过是指这一系列的文本文件名称,没有具体写出代码
while (!feof(fp)){
    fscanf(fp,"%d\n",&temp);
    (*ptr)=temp;
    ptr++;
}
fclose(fp);
运行时提示错误,请指正!第二个,用CArray<int,int> temp_array;
int temp;
fp=fopen("*.txt","r");
while (!feof(fp)){
    fscanf(fp,"%d\n",&temp);
    temp_array.add(temp);
}
运行时根本跑不动,近似于死机状态。
===================================================================================
各位有没有什么好的方法?!!!

解决方案 »

  1.   

    用指针要先申请内存分配
    还有,你说文件中的数据是生成BYTE的数组,怎么我有看到400(>255)可不是byte取值范围。
      

  2.   

    哦,笔误,文件的数据中没有400这么大的数字,都是小于255的,请问申请内存应该怎么做?
    是不是int *ptr;然后就可以
    (*ptr)=temp;ptr++了?另外,如果申请内存,就一定会更快么?多谢!
      

  3.   

    CStdioFile fMyFile;
        CStringArray FileContainer;
        bFileExist=fMyFile.Open(m_sFileName, CFile::modeRead); if(!bFileExist)
    {
    return FALSE;
    } CString strline;
    FileContainer.RemoveAll(); while(fMyFile.ReadString(strline))
    {
    FileContainer.Add(strline);
    } fMyFile.Close();
      

  4.   

    这个错误的也太多了点吧?对于BYTE*,它的++只是简单的加上一个字节,这样的话,肯定会产生后面的数据覆盖前面的,很可能到结束的时候就只有最后一个数据时正确的……一般来说使用C来写代码会比C++的代码效率高很多……特别是当C++还使用了template的时候,效率更不容易控制……2M的数据其实也不大,但是问题在于你保存数据的方式是文本,而不是二进制,如果是二进制数据的话,只要fopen,fseek,ftell,malloc然后直接fread就可以了,效率会高很多,不如你把你的数据改成用2进制保存的……
      

  5.   

    C*类的效率肯定比数组差多了,你还是用数组就好。
    至于分配空间,你访问一个指针之前必须为它指向的位置分配空间的啊,而不是分配了空间会更快。
    分派空间可以用malloc函数。如果你声明的是一个数组,然后又把指针指向数组首地址,那就已经分配了do空间了。
    newbiestar说的覆盖,应该没有这样的问题。
    至于采用什么格式,如果是经常存取的话,二进制要好得多,速度快,而且可以随机访问;但是如果在很长一段时间只读写一次的话,文本也无所谓啦。
    另外,dos格式的文本是"\r\n"换行的,我不知道你用"\n"读取会不会有问题。
      

  6.   

    如果每一个\n都来读一下的话(假设是1ms)
    总时间就是2000000*1ms = 2000秒  /60 = 30分钟左右用CFile:
    char *p = NULL;
    try{
    CFile cf("*.txt", CFile::modeRead);
    DWORD dwlen = cf.GetLength();
    p = new char[dwlen];
    if(p) cf.HugeRead(p,dwlen);
    }
    catch(CFileExecption &e)
    {
    ...
    }
    之后再用程序来判断\r\n
      

  7.   

    内存分配可以用new BYTE[数组大小]
    对于你采用的第二种方式,建议用
    CByteArray
    且做如下调用:
    const int KMAXSIZE = 3000000; //一个通常情况下大于实际可能数组大小的值
    CByteArray temp_array;
    temp_array.SetSize( KMAXSIZE, KMAXSIZE / 8 );
    这样CByteArray的运算性能表现上会接近于指针运算处理数组
    调用完以后可以看需要调用方法FreeExtra释放多出来的空间
      

  8.   

    回复人: daseny(胡杨) ( ) 信誉:100  2005-05-26 09:03:00  得分: 0  
     
     
       C*类的效率肯定比数组差多了,你还是用数组就好。
    至于分配空间,你访问一个指针之前必须为它指向的位置分配空间的啊,而不是分配了空间会更快。
    分派空间可以用malloc函数。如果你声明的是一个数组,然后又把指针指向数组首地址,那就已经分配了do空间了。
    newbiestar说的覆盖,应该没有这样的问题。
    至于采用什么格式,如果是经常存取的话,二进制要好得多,速度快,而且可以随机访问;但是如果在很长一段时间只读写一次的话,文本也无所谓啦。
    另外,dos格式的文本是"\r\n"换行的,我不知道你用"\n"读取会不会有问题。
      
     
    ==========================================
    你不相信么?那你就去试试看,BYTE*就是unsigned char,你看看你调用了++操作符以后地址+4字节还是+1字节……另外\n和\r\n没有区别,因为fopen的参数是"r"而不是"rb",所以不存在差别,都是一样的,fscanf自己能认得这些东西……
      

  9.   

    我帮你分析一下你的第一种方式为什么会错,解决办法楼上的同志们都已经说过了,我就不在费话了 :P
    方式一:
    int temp;
    fp=fopen("*.txt","r");//(这里的*.txt)只不过是指这一系列的文本文件名称,没有具体写出代码
    while (!feof(fp)){
        fscanf(fp,"%d\n",&temp);
        (*ptr)=temp; //看这,你怎么可以把一个整型数赋给字节类型变量呢?
        //改成(*ptr) = (BYTE)temp; 就对了
        ptr++;
    }
    fclose(fp);
      

  10.   

    CFile pfile;
    CString strFileName;
    long int nlen;

        //open and read file obtain information
    CFileDialog Dlg(true,"txt",NULL,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT, "*.TXT | *.txt",this);
    if (Dlg.DoModal() == IDOK)
    {   
    strFileName = Dlg.GetPathName();
    m_Path = strFileName;
    UpdateData(false);
    if(pfile.Open(strFileName.GetBuffer(0),CFile::modeRead))
    {              
    BYTE* buffer;
    //obtain file length
    nlen = pfile.GetLength();
    if (nlen)
    {
     buffer = new BYTE[nDataLen];


    if(pfile.ReadHuge(buffer,nDataLen)) //read huge file obtain file length
    {
    HandleData(buffer,nDataLen);
    }
    if(buffer != NULL)
    {
    delete[] buffer;
    pfile.Close();
    }
                         }
    }
    }
    void CRemovenoiseView::HandleData(BYTE *buffer, int nLen)

    //这里就可以对数组进行操作了
    }