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

时间:2014-04-17 10:19:04

标签: ios c text ascii non-ascii-characters

我有一个vb6程序,它从sql server读取数据并将它们写入文本文件。每个记录由换行符分隔。 必须在sqlite数据库中读取和写入这些文件(也可以是> 200mb)。 为避免内存警告,我在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而不是正确的。 你知道你帮帮我吗?谢谢!

1 个答案:

答案 0 :(得分:1)

以下行告诉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 aka Code Page 1251(常量NSWindowsCP1251StringEncoding来自的地方)。

您可以或多或少地验证它。如果打开包含欧元符号(€)的文本文件,则必须使用值80(十六进制),如果它在CP 1251中编码。在Latin-1(又名ISO-8859-1)中,您不能表示欧元符号。在Latin-9(又名ISO-8859-15)中,它将使用A4(十六进制)。在UTF-8中,需要三个字节:E2 82 AC。

请亲自检查一下。如果您不确定,请添加文本文件相关部分的十六进制转储。