【问题标题】:C for loop not printing correctly, characters out of orderC for 循环无法正确打印,字符乱序
【发布时间】:2023-03-20 23:50:01
【问题描述】:

编辑:我现在意识到我需要问的问题是我将如何捕获 dat 文件“^M”中的回车符,如下所示抛出我的输出。

我的程序从文件中读取字符,将它们放入数组中,一旦数组已满,它就会转储输入。该文件包含我猜可能导致问题的特殊字符。我正在读取字符,然后以十六进制格式打印它们的数值,然后在下一行我想以字符形式打印相同的信息。

谁能告诉我为什么我的for 循环似乎跳来跳去?数组可能加载不正确吗?

file.dat 文件 -- 在 of 之后包含标签

This is a test of               program^M

Special characters are: ^L ^H ^K

OUTPUT: -- 输出以 %x 格式打印

54 68 69 73  69 73  61  74 65 73 74  6f 

66   70 72 6f 67 72 61 6d d  53 70 

65 63 69 61 6c  63 68 61 72 61 63 74 65 72 73 

 61 72 65 3a  c  8  b   ffffffff 72 73 

十六进制格式的输出是正确的,翻译后就是我想要和需要的输出

OUTPUT: -- 输出错误乱序

T h i s  i s  a  t e s t  o 

   S p  o g r a m 3 

e c i a l  c h a r a c t e r s 

 a r e :  

                ? r s 

这个输出显然是错误的,让我很困惑。我不明白一个简单的for 循环是如何导致这个输出的。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void print_group(char array[]);
void print_space(int num);
void printbits(int bits);
int main()
{
    char array[16];
    char i_file;
    int count = 0;
    FILE *fp;
    int bits = 0;
    int a = 0;

    fp = fopen("file.dat","r");

    if( fp == NULL)
    {
        printf("ERROR");
    }
    else
    {
        while (!feof(fp)) /*while pointer hasnt reached end of file continue loop*/
        {
            array[count] = fgetc(fp);

            if(count == 15 || feof(fp))
            {
                print_group(array);
                count = -1;
                printf("\n");
            }
            count++;
        }
    }

    fclose(fp);

    return 0;
}

void print_group(char array[])
{
    int a;
    int num;

    for(a = 0; a <= 15; a++)
    {
        /*This for loop wil print the numbers that are associated with the dump
        of the array.*/
        if(array[a] == ' ' || array [a] == '\t' || array[a] == '\n' || array[a] == '\?')
        {
            printf("20 ");
        }
        else
            printf("%x ",array[a]);
    }

    printf("\n");

    for(a = 0; a <= 15; a++)
    {
        /*This for loop wil print the characters that are associated with the dump
        of the array.*/
        if (array[a] == ' ' || array [a] == '\t' || array[a] == '\n' || array[a] == '\?') {
            printf(" ");
        }
        else
            printf("%c ",array[a]);
    }
}

void print_space(int num)
{}

【问题讨论】:

  • 在两个for 循环中尝试if(array[a] &lt;= ' ')
  • 一个提示:如果您的文件大小不是 16 字节的倍数,则从文件中读取的最后一个块的最后一部分将包含来自前一个读取块的数据。要在你 print_group(array); 之后摆脱它,将数组设为 0:memset(array, 0, 16)。此外,在以十六进制打印时,请指定%02X 格式说明符而不是%x ,以明确它是一个十六进制字符串。
  • 虽然它不太可能导致您的意外输出,但您确实错误地使用了feof()。见stackoverflow.com/questions/5431941/…
  • 旁注:在第一个输出循环中,if 语句应该被删除。所有十六进制值都应按原样打印。
  • 你的特殊字符的十六进制数是多少?

标签: c arrays special-characters fgetc


【解决方案1】:

while(!eof) 错误

在调用 feof() 之前,始终需要检查读取的返回值(fread()、fscanf() 或 fgetc())。

就像它比您预期的多一次进入循环一样。如果出现读取错误,则循环永远不会终止。

试试:

int c;

while ((c = fgetc(fp)) != EOF) {
    // do something with c
}
if (ferror(fp)) {
    // handle the error, usually exit or return
} else {
    // continue execution
}

还有很多其他帖子对此进行了解释。

【讨论】:

  • 是 if 和 else 应该在 while 内
  • 没有。正常情况 - 一旦你在读取 (fgetc(fp)) 时点击 EOF char,你将退出循环并转到 else else 语句。
【解决方案2】:

^M 是回车。当您打印它时,光标会返回到最左边的位置,但不会移动到下一行。第二批16个字符是f program^M Sp,所以在打印^M并回车后,Sp会覆盖之前的内容(即f pr)。

【讨论】:

  • 我怎样才能赶上 ^M 回车。当我尝试比较 ^M 时,我得到一个编译错误 -------lab.c:89: 警告:由于数据类型的范围有限,比较总是错误的
  • @johnwayne 在 C 中,回车是 '\r'
  • ^M 在我更改代码时被捕获,但 ^L ^H ^K 给我这个 ------\n? r s
【解决方案3】:

我不确定这是否会有所帮助。但是在你已经到达文件末尾并且数组索引没有达到 15 的情况下,你没有打印数组之前插入的字符吗?

也许您的数组索引应该从 0 到计数。

这可能是显示垃圾字符的原因。

【讨论】:

  • 好点,当我尝试这个时,唯一的问题是它只能进入计数为 15 或文件结尾的函数......当它在文件末尾时,计数仍然是 13 所以无论如何,它都会打印内存位置。如果您还有其他很棒的建议。我想不出合适的计数方法
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多