簡體   English   中英

在ios上的C中讀取大文本文件

[英]Read large text file in C on ios

我有一個vb6程序,該程序從sql server中讀取數據並將其寫入文本文件。 每個記錄都由換行符分隔。 這些文件(也可能大於200mb)必須在sqlite數據庫中讀取和寫入iPad。 為了避免出現內存警告,我在C中使用此功能讀取了文件的每一行

“ strRet”是用C讀取的字符串

“ NSString * stringa”是轉換為NSString的字符串C

NSDictionary *readLineAsNSString(FILE *f,int pospass,BOOL testata,int primorecord  )
{
    char *strRet = malloc(BUFSIZ);//(char *) togliere perche con c potrebbe restituire un int
    if (strRet==NULL)
    {
        return nil;
    }

    int size = BUFSIZ;

    BOOL finito=NO;
    int pos = 0;
    int c;
    fseek(f,pospass,SEEK_SET);

    do{ // read one line

        c = fgetc(f);

        if (pos >= size-1)
        {
            size=size+BUFSIZ;
            strRet = realloc(strRet, size);
            if (strRet==NULL)
            {
                return nil;
            }

        }

        if(c != EOF)
        {
            strRet[pos] = c;
            pos=pos+1;
        }
        else
        {
            finito=YES;
        }

    }while(c != EOF && c != '\n');

    if (pos!=0)
    {
        strRet[pos] = '\0';
    }

    NSString *stringa=[NSString stringWithCString:strRet encoding:NSASCIIStringEncoding];

    if (pos==0)
    {
        stringa=@"";
    }

    long long sizerecord;
    if (pos!=0)
    {
        sizerecord=   (long long) [[NSString stringWithFormat:@"%ld",sizeof(char)*(pos)] longLongValue];
    }
    else
    {
        sizerecord=0;
    }
    pos = pospass + pos;

    NSDictionary *risultatoc = @{st_risultatofunzione: stringa,
                                 st_criterio: [NSString stringWithFormat:@"%d",pos],
                                 st_finito: [NSNumber numberWithBool:finito],
                                 st_size: [NSNumber numberWithLongLong: sizerecord]
                                 };

    //Svuoto il buffer
    free(strRet);
    // free(tmpStr);
    strRet=NULL;

    return risultatoc;

}

但是,碰巧當我在文件中有特殊字符(例如€符號或帶重音的字母或某些北歐國家)時,記錄無法正確讀取,並且我發現自己使用的是隨機字符的NSString而不是正確對象,真愛。 你知道你幫我嗎? 謝謝!

以下行告訴iOS您具有ASCII數據:

NSString *stringa= [NSString stringWithCString:strRet encoding:NSASCIIStringEncoding];

但是,€符號或帶重音的字母不是ASCII的一部分。 所以您顯然有不同。

找出它是什么編碼(例如UTF-8,Windows ANSI,ISO-8859-1)並相應地更新該行,例如:

NSString *stringa= [NSString stringWithCString:strRet encoding: NSWindowsCP1251StringEncoding];

更新

弄清楚正在使用哪種編碼可能很棘手。

根據我的經驗,VB6和SQL Server是很好的一對,因為它們通常不會弄亂編碼。 較弱的部分是文本文件,它取決於編碼,但不包含有關使用哪種編碼的任何顯式信息。 VB6可能使用Windows默認設置,具體取決於您的語言設置。 不幸的是,我不知道在Windows哪里可以看到默認編碼。

在西方國家,編碼通常設置為Windows ANSI,即“代碼頁1251”(這是常量NSWindowsCP1251StringEncoding來源)。

您可以或多或少地對其進行驗證。 如果打開包含歐元符號(€)的文本文件,則如果它是用CP 1251編碼的,則必須使用值80(十六進制)。在Latin-1(又名ISO-8859-1)中,您不能表示歐元符號。 在Latin-9(aka ISO-8859-15)中,它將使用A4(十六進制)。 在UTF-8中,將需要三個字節:E2 82 AC。

因此,請自己檢查。 如果不確定,請添加文本文件中相關部分的十六進制轉儲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM