| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2860 人关注过本帖, 1 人收藏
标题:输出文件内容,汉字乱码
只看楼主 加入收藏
young
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:223
专家分:160
注 册:2004-9-5
收藏
得分:0 
回复 9楼 aneeg
由于汉字比较多,一个字节仅能表示256个,所以一个字节不行

如果你爱C语言,请你爱指针; 如果你爱指针,请你爱指针的指针;
2015-02-11 20:53
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:2 
哪的官方?

授人以渔,不授人以鱼。
2015-02-11 21:32
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你這個“官方”源碼本來就沒考慮漢字問題,何況還過濾了回車符,失真的倒序輸出(在Linux下的文本會以'\r'回車換行,但在MS系統下還有'\n',它在這個代碼下會顯示出來,結果呈階梯形,因爲沒回車衹換行),沒什麽意義。

[ 本帖最后由 TonyDeng 于 2015-2-11 23:29 编辑 ]

授人以渔,不授人以鱼。
2015-02-11 23:27
aneeg
Rank: 1
等 级:新手上路
帖 子:75
专家分:8
注 册:2014-4-10
收藏
得分:0 
回复 13楼 TonyDeng
primer plus里的,我在想,注释里的/*针对 DOS, 在 UNIX 下也可工作*/是指让过滤掉dos文件中的\r以便在unix中显示正常?是有点怪。
2015-02-12 01:58
aneeg
Rank: 1
等 级:新手上路
帖 子:75
专家分:8
注 册:2014-4-10
收藏
得分:0 
回复 13楼 TonyDeng
那怎么处理汉字啊,字符输入输出函数不管用,只能用字符串,怎么鉴定一个汉字结尾阿
2015-02-12 02:00
young
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:223
专家分:160
注 册:2004-9-5
收藏
得分:0 
根据你的程序,我写了demo程序,仅限于ascii和GB2312的文本倒置,在window下用VC编译通过并简单测试。

#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032'    /* DOS 文本文件中的文件结尾标记 */
#define SLEN 50
int main (void)
{
    char file[SLEN];
    FILE *fp;
    FILE *fpout;
    unsigned char *pSrc;
    unsigned char *pDes;
    int textSize, iCount;

    puts ("Enter the name of the file to be processed : ");
    gets(file);
    if ((fp = fopen(file, "rb")) == NULL)
    {      /* 只读和二进制模式 */
        printf ("reverse can't open %s \n",file);
        exit(1);
    }
    fseek(fp,0L, SEEK_END);   /* 定位文件结尾处 */
    textSize = ftell(fp);
    fseek(fp,0L, SEEK_SET);

    pSrc = (unsigned char*)malloc(textSize+2);
    if(NULL == pSrc)
    {
        printf ("pSrc = NULL\n");
        return 0;
    }
    pDes = (unsigned char*)malloc(textSize+2);
    if(NULL == pDes)
    {
        printf ("pDes = NULL\n");
        return 0;
    }
    memset(pSrc, 0, textSize+2);
    memset(pDes, 0, textSize+2);
    fread(pSrc, sizeof(unsigned char), textSize, fp);

    //pDes = pDes+textSize-1;
    iCount = 0;
    while(*(pSrc+iCount))
    {
        if((*(pSrc+iCount)) <= 0x7f)
        {
            if((*(pSrc+iCount)==13) && (*(pSrc+iCount+1)==10))    // 回车换行
            {
                *(pDes+textSize-1-iCount) = *(pSrc+iCount+1);
                *(pDes+textSize-1-iCount-1) = *(pSrc+iCount);
                iCount+=2;
            }
            else
            {
                *(pDes+textSize-1-iCount) = *(pSrc+iCount);
                iCount+=1;
            }
        }
        else
        {
            *(pDes+textSize-1-iCount) = *(pSrc+iCount+1);
            *(pDes+textSize-1-iCount-1) = *(pSrc+iCount);
            iCount+=2;
        }
    }

    if ((fpout = fopen("out.txt", "wb")) == NULL)
    {
        printf ("reverse can't open out.txt \n");
        exit(1);
    }
    fwrite(pDes, sizeof(unsigned char), textSize, fpout);
    if(pSrc)
    {
        free(pSrc);
    }
    if(pDes)
    {
        free(pDes);
    }
    if(fp)
    {
        fclose(fp);
    }
    if(fpout)
    {
        fclose(fpout);
    }

    return 0;
}

如果你爱C语言,请你爱指针; 如果你爱指针,请你爱指针的指针;
2015-02-12 10:07
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:2 
好像不是太复杂,就只需考虑区别ascii码和汉字内码即可,下述代码在win控制台下可运行:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032'    /* DOS 文本文件中的文件结尾标记 这个有吗?*/
#define SLEN 50
int main (void)
{
   char file[SLEN];
   char ch,cc[3]={0};//增加一个显示汉字的字符数组缓冲
   FILE *fp;
   long count, last;

   puts ("Enter the name of the file to be processed : ");
   gets(file);
   if ((fp = fopen(file, "rb")) == NULL)
   {      /* 只读和二进制模式 */
      printf ("reverse can't open %s \n",file);
      exit(1);
   }
   fseek(fp,0L, SEEK_END);   /* 定位文件结尾处 */
   last = ftell(fp);
   for (count = 1L; count <= last; count++)
   {
      fseek(fp,-count,SEEK_END); /* 回退 */
      ch = getc(fp);
   /* 针对 DOS, 在 UNIX 下也可工作 */
   //   if (ch != CNTL_Z && ch != '\r')  13 10是回车换行符号,不论前后都执行同样操作

      if(ch>0)
      {
          putchar(ch);//显示普通asc字符,同时清除汉字显示缓冲
          cc[1]=0;
      }
      else
      {
          if(cc[1]!=0)
          {
              cc[0]=ch;
              printf("%s",cc);//显示汉字
              cc[1]=0;
          }
          else
              cc[1]=ch;
      }
    }
    putchar('\n');
    fclose(fp);
    return 0;
}



[ 本帖最后由 wmf2014 于 2015-2-12 11:08 编辑 ]

能编个毛线衣吗?
2015-02-12 11:07
aneeg
Rank: 1
等 级:新手上路
帖 子:75
专家分:8
注 册:2014-4-10
收藏
得分:0 
回复 17楼 wmf2014
可以实现,多谢。第一个cc[1]=0是干什么的,删去没影响吧。还有就是把一个汉字分成两个字符读取输出,万一有一个配对错误,后面的岂不是全错了
2015-02-12 13:44
aneeg
Rank: 1
等 级:新手上路
帖 子:75
专家分:8
注 册:2014-4-10
收藏
得分:0 
回复 16楼 young
这个好复杂,我消化消化,多谢
2015-02-12 13:45
young
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:223
专家分:160
注 册:2004-9-5
收藏
得分:0 
回复 19楼 aneeg
恩,我的程序读大文件时占内存比较大,把文件一次性读到内存,速度会快很多,文件操作是很耗时的,你可以找个上M的txt文件试试。

如果你爱C语言,请你爱指针; 如果你爱指针,请你爱指针的指针;
2015-02-12 14:31
快速回复:输出文件内容,汉字乱码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018750 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved