【问题标题】:My C file is writing random characters我的 C 文件正在写入随机字符
【发布时间】:2016-04-23 03:07:34
【问题描述】:

我正在用 C 创建一个战舰游戏,但是在这个函数中,为了在记录文件中放置一条新记录,并保持它的顺序,该函数在文件中写入了很多随机字符。 以下是结构:

typedef char nom_tipus [MAX_NOM];

typedef struct
{
    nom_tipus nom;
    int puntuacio;
} record_tipus;

这里是一个假定结果的示例:

TestDeunum 300ASDF 151AAA 150BBB 149CCC 148DDD 140140142JJJJJ1341KKK 140LLL 139MMM 138NN 137OO 136PPP 135QQQ 134RRR 133SS 132TTT 131UUU 130VV129“

这是最终文件:

Name 360mfuÿ<a    |ø`    H 300f   Iufu{<a    ` †lÔwúÒwÿÿÿÿ$   xø`        G»ðÛ—   akhud    ylu    ø` …thu¸?muàø` ¢ihu   ssgujsgu–   b   bu   ylu´ø` 0.buLkÔw\1«uL                151akhud    ylu    ø` …thu¸?muàø` ¢ihu   ssgujsgu–   b   bu   ylu´ø` 0.buLkÔw\1«uL                150b   bu   ylu´ø` 0.buLkÔw\1«uL                149cù` 0                   m1«uiÐw    (ú` L          ”   d                   (ú`          bu0ú`      “   e Œ®PØ€ù` B¤Òw0p@         €,@ àù` 4@ 0p@ 5n ú` ’   fHì¯      -@   @            ø1n p.n Ôù` ®jÔw  @ ‘   gkÔw\1«uL   <kÔwéïªu                148d                   (ú`          bu0ú`      “   e Œ®PØ€ù` B¤Òw0p@         €,@ àù` 4@ 0p@ 5n ú` ’   fHì¯      -@   @            ø1n p.n Ôù` ®jÔw  @ ‘   gkÔw\1«uL   <kÔwéïªu                147e Œ®PØ€ù` B¤Òw0p@         €,@ àù` 4@ 0p@ 5n ú` ’   fHì¯      -@   @            ø1n p.n Ôù` ®jÔw  @ ‘   gkÔw\1«uL   <kÔwéïªu                146fHì¯      -@   @            ø1n p.n Ôù` ®jÔw  @ ‘   gkÔw\1«uL   <kÔwéïªu                145gkÔw\1«uL   <kÔwéïªu                144h¼B3    0ú` $¨iuÄú` 8ú` Ãeu\ú` Pmup     Ðü` ¬iu   imu¬ú`        ’³iu€ú` 
   Pmu€ú` $¨iuý` ˆú` ÃeuŽ   jmup      143imu¬ú`        ’³iu€ú` 
   Pmu€ú` $¨iuý` ˆú` ÃeuŽ   jmup      142jmup      141k ¨ ý`         -ú`              B            Œ   l   (mu    ÿQ@ 6ïiu      ýÿÿÿxý` @   d   Cý` …üiu‹   mmumu    :þiuPmup ¨ ÿÿÿ”û` tý` xý` °ý`  P@ Š   n  °ý`           ”û`            ¤û`          ‰   o   muÜû       ÿ IÄfu+?amud       mu       ˆ   p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 140l   (mu    ÿQ@ 6ïiu      ýÿÿÿxý` @   d   Cý` …üiu‹   mmumu    :þiuPmup ¨ ÿÿÿ”û` tý` xý` °ý`  P@ Š   n  °ý`           ”û`            ¤û`          ‰   o   muÜû       ÿ IÄfu+?amud       mu       ˆ   p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 139mmumu    :þiuPmup ¨ ÿÿÿ”û` tý` xý` °ý`  P@ Š   n  °ý`           ”û`            ¤û`          ‰   o   muÜû       ÿ IÄfu+?amud       mu       ˆ   p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 138n  °ý`           ”û`            ¤û`          ‰   o   muÜû       ÿ IÄfu+?amud       mu       ˆ   p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 137o   muÜû       ÿ IÄfu+?amud       mu       ˆ   p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 136p   @þ` ðÑguŸBþÿÿÿôû` 1iumumud   „ü`  ü` 6ïiu‡   qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØfu   €Øfuo8a   …   sü` Õ§fuܧfu_8a   (mu              ¤ü` Þ¬fuø „   tØfu   €Øfu8a   (mu    8a$      ´ü`    Xý` ƒ   uBþÿÿÿ€Øfu…3iu   à 135qü` ¤iu
      d   þ` …üiuø Xü` Õ§fuܧfu¯8a   †   r             Tü` Þ¬fuø ˜ü` UØf"

代码如下:

#define MAX_RECORDS     25
#define MAX_NOM         50

bool emmagatzema_records(int punts, nom_tipus nom) {
    int i, j;
    char n;
    record_tipus records[MAX_RECORDS];
    FILE *f;

    f = fopen("fitxer_records.txt", "r");
    i = 0;
    while (i < MAX_RECORDS) {
        j = 0;
        fscanf(f, "%c", &n);
        while (n != ' ' && j < MAX_NOM) {
            records[i].nom[j] = n;
            fscanf(f, "%c", &n);
        }
        fscanf(f, "%d", &records[i].puntuacio);
        if (punts > records[i].puntuacio) {
            if (i == MAX_RECORDS - 1) {
                records[i].puntuacio = punts;
                for (j = 0; j < MAX_NOM; j++) {
                    records[i].nom[j] = nom[j];
                }
            } else {
                records[i + 1].puntuacio = records[i].puntuacio;
                records[i].puntuacio = punts;
                for (j = 0; j < MAX_NOM; j++) {
                    records[i + 1].nom[j] = records[i].nom[j];
                }
                for (j = 0; j < MAX_NOM; j++) {
                    records[i].nom[j] = nom[j];
                }
                punts = 0;
                i = i + 1;
            }
        }
        i = i + 1;
    }
    fclose(f);

    f = fopen("fitxer_records.txt", "w");
    for (i = 0; i < MAX_RECORDS; i++) {
        j = 0;
        while (records[i].nom[j] != ' ' && j < MAX_NOM) {
            fprintf(f, "%c", records[i].nom[j]);
            j = j + 1;
        }
        fprintf(f, "%c", ' ');
        fprintf(f, "%d", records[i].puntuacio);
    }
    return true;
}

【问题讨论】:

  • 你应该对文件内容使用代码格式,这样更容易阅读。
  • @AB.S:请不要修复问题中的代码,这会使讨论不一致。
  • 不确定它是否相关,但您在函数结束时未调用 fclose,从而泄漏了打开的文件句柄。
  • 是的,我以前修过,但对我没有帮助。
  • 为了便于我们人类理解,1)请遵循公理:每行只有一个语句,并且(最多)每个语句一个变量声明。 2) 用空行分隔代码块(for、if、else、while、do...while、switch、case、default)

标签: c windows codeblocks


【解决方案1】:

在一次读取一个字符的字符串时,您永远不会增加 j

while (n!=' ' && j<MAX_NOM)
{
    records[i].nom[j++]=n;  // note `j` changed to `j++` 
    fscanf(f, "%c", &n);
}

当然,这并不是读取字符串的常用方法。您应该改用fgets 之类的东西。而且你真的应该检查 I/O 错误。

【讨论】:

  • 没错,但它会继续为文件提供随机字符。关于 fgets……教授在这个项目中“禁止”了 fgets。
  • 只是为了确保这不是未定义的行为,您应该在问题中包含struct record_tipus 的定义。也可能是nom_tipus
  • @AB.S:他们的姿势多么愚蠢!他们应该坚持正确的代码缩进和表示。你至少可以用int c = getc(f);替换fscanf(f, "%c", &amp;n);并正确测试EOF,或者使用fscanf(f, "%49s", records[i].nom)一步读取名称并测试返回值。
  • 由于您没有错误处理,从空读取文件时可能会损坏文件。看起来该程序旨在将不断增长的数据结构存储在磁盘而不是内存中。然后你遇到的一个问题是records 从未初始化为任何东西。任何对fscanf 的调用失败都将不会改变你给他们的记忆。因此,结构可能没有正确添加新项目,因为它在整个地方复制未初始化的名称(由于您拥有的排序规则)。初始化数组并处理 I/O 故障,然后重试。
  • 首先,错误将从函数外部处理。该文件将始终被旧记录或预定义记录(aaa 10bbb 9ccc 8 ...)填充。即将初始化数组,我不明白你的意思......对不起我的未知,但我在这个世界上几乎是新人......
猜你喜欢
  • 2012-06-16
  • 2021-03-11
  • 2013-05-15
  • 2016-09-06
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多