【问题标题】:C for loop to iterate array different from putcC for循环迭代不同于putc的数组
【发布时间】:2013-11-23 22:58:16
【问题描述】:

我正在尝试从文本文件中读取,对于非打印 ascii 字符,我想打印出“^”+“G”作为 BELL 字符的示例。很像 unix 的 cat -v 命令。问题发生在我应该存储字符的 for 循环中,直到我点击换行符然后将它们打印出来。 for 循环为 ctrl+G 打印“G”,为测试打印“t”“e”“s”“t”。

int readFile(FILE* inputFile) {

char input[5];
char *arrayEnd = &input[5]+1;

int anyChanges = 1;
int iochar = 0;
int i = 0;
//get index of new line
//substring of position until new line
//print substring position to end.
int printedColumns = 0;
//credit Foster Chapter 2
while (( iochar = getc(inputFile) ) != EOF )
{   //Returns 1 if no changes made, return 0 if any changes have been made.
    //printf("character --> %c\n",iochar);
    if(iochar != '\n') {
        //This if statement checks for normal ascii characters.
        //If the output is less than 72 it prints it and increments printedColumns.
        if (( ' ' <= iochar ) && ( iochar <= 126 ) ) {
            if(*(input + i) == *arrayEnd)
            {
                i = 0;
            }
            *(input +i) = iochar;
            //printf("input array ---> %c\n",input[i]);
            //printf("i:%d\n",i);
            //printf("iochar:%d\n",iochar);
            //putc(*(input+i), stdout);
            i++;
            }
        //This if statement checks for the non-printing characters.
        //New line is not included because it is a special case that is accounted for below
        if (iochar <= 31)  {

            if (*(input + i) == *arrayEnd)
            {
                i = 0;
            }
                *(input + i) =94;
                  putc(*(input+i), stdout);
                i++;

            if(*(input+i)== *arrayEnd)
            {
               i = 0;
            }
                *(input + i) = iochar + 64;
                putc(*(input+i), stdout);
                printf("\n");
                i++;

        }
        int b = 0;
        for (b = 0;b<6;b++){
            putc(*(input+b),stdout);
        }
}//end if != '\n'
}//end while
return anyChanges;
}//end function

【问题讨论】:

  • man ctype, esp isprint
  • 不要使用数字;使用像'^' 这样的字符常量而不是94。为什么不在阅读时输出每个字符的翻译?您使用的微小(5 个字符)缓冲区有什么好处?
  • 我想最终打印最后 72 列,所以我将缓冲区变小以进行测试。

标签: c


【解决方案1】:

这似乎做了很多你正在寻找的事情:

#include <stdio.h>

static
int readFile(FILE *inputFile)
{
    int numChanged = 0;
    int iochar = 0;

    while ((iochar = getc(inputFile) ) != EOF)
    {
        if ((' ' <= iochar && iochar <= 126) || iochar == '\n')
            putc(iochar, stdout);
        else if (iochar < ' ')
        {
            putc('^', stdout);
            putc(iochar + 'A' - 1, stdout);
            numChanged++;
        }
        else
            numChanged++;
    }
    return numChanged;
}

int main(void)
{
    printf("Number of changed characters: %d\n", readFile(stdin));
    return 0;
}

它在自己的源代码上正常工作(没有要更改的字符——源代码中没有标签),而且它似乎在自己的二进制文件上也能正常工作。这两个输出都不足以令人兴奋地在这里引用。请注意,它会删除代码 0x7F 到 0xFF 中的字符。您可以通过针对您选择指定的任何规则适当地调整 else 子句来修改它。问题是对这些角色的处理方式保持沉默。

如果需要一行的最后 72 个字符,则需要读取整行;滚进来fgets()

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

static
int readFile(FILE *fp)
{
    int numChanged = 0;
    char line[4096];

    while (fgets(line, sizeof(line), fp) != 0)
    {
        size_t len = strlen(line);
        if (line[len-1] != '\n')
            break;  // Damn! Line to long
        size_t start = 0;
        if (len > 72)
            start = len - 72;
        for (size_t i = start; i < len; i++)
        {
            /* The next line is only 70 characters long, but this comment should be truncated */
            if ((' ' <= line[i] && line[i] <= 126) || line[i] == '\n')
                putc(line[i], stdout);
            else if (line[i] < ' ')
            {
                putc('^', stdout);
                putc(line[i] + 'A' - 1, stdout);
                numChanged++;
            }
            else
                numChanged++;
        }
    }
    return numChanged;
}

int main(void)
{
    printf("Number of changed characters: %d\n", readFile(stdin));
    return 0;
}

这段代码是独立运行的,经过精心组合的源代码,产生了有趣的部分:

            start = len - 72;
        for (size_t i = start; i < len; i++)
        {
ine is only 70 characters long, but this comment should be truncated */
            if ((' ' <= line[i] && line[i] <= 126) || line[i] == '\n')
                putc(line[i], stdout);
            else if (line[i] < ' ')
            {

你可以决定我在计算长度时是否有一个错误。

【讨论】:

  • 这可以满足我的要求,但我只想打印每行的最后 72 个字符,这就是我尝试做缓冲区的原因。不过,这些常量非常有用。
  • 好的;请预先说明所有复杂因素。其他参与规则是什么?有什么我们不能用的功能或者什么讨厌的东西?
猜你喜欢
  • 2012-01-05
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多