以某种方式显示输出

时间:2016-08-02 03:18:33

标签: c

我正在尝试打印文本文件中所有字符的ASCII值。

int main(int argc, char* argv[]) {
        FILE *fp;
        int c;
        fp = fopen(argv[1], "r");
        while((c = fgetc(fp)) != EOF) {
                printf("%c %3d\n", c, (int)c);
        }
        fclose(fp);
        return 0;
}

是否可以显示如下所示的输出?

r     a     n     d     o     m
114   97   110   100   111   109

假设输入文件中的第一个单词是随机的'。感谢

3 个答案:

答案 0 :(得分:2)

是的,正如hexiecs所述,这是非常可能的。问如何会是一个更好的问题。我会假设这就是你的意思。

以下是您可能会如何执行此操作的示例:

#include <stdio.h>
#define NEW_TERMINAL_LINE 10

void print_current_characters(char char_equivalents[]);

int main(int argc, char const *argv[]) {
  char char_equivalents[NEW_TERMINAL_LINE] = {0};

  int c;
  int i = 0;
  int final_position; /* Store the final position that we will use later
                       * to get the remaining characters in the buffer */

  FILE *file;
  file = fopen("file.txt", "r");
  if (file) {
    while ((c = getc(file)) != EOF) {
        if (i > NEW_TERMINAL_LINE - 1) {
          /* Every time the buffer fills up, we need to go to a new line
           * in the output as well (defined by NEW_TERMINAL_LINE).
           * Then we need to clear the buffer and make a new line 
           * to start off printing again!
          */
          print_current_characters(char_equivalents);
          int j;
          for (j = 0; j < sizeof(char_equivalents)/sizeof(char_equivalents[0]); j++) {
            char_equivalents[j] = 0; /* Clear the filled up buffer */
            i = 0;
          }
          printf("\n\n");
        }
        /* Print the character itself (we will print the ASCII when the buffer fills up) */
        char_equivalents[i] = c;
        if(char_equivalents[i] == '\n') {
          printf("\\n\t");
        } else if (char_equivalents[i] == '\t') {
          printf("\\t\t");
        } else if (char_equivalents[i] == ' ') {
          printf("[space]\t");
        } else {
          printf("%c\t", c);
        }
        final_position = i;
        i++;
    }

    /* Print any remaining characters in the buffer */
    print_current_characters(char_equivalents);

    fclose(file);
  }
  printf("\n");
  return 0;
}
void print_current_characters(char char_equivalents[]) {
  printf("\n");
  int i;

  for(i = 0; i < NEW_TERMINAL_LINE; i++) {
    if (char_equivalents[i] == 0 || NULL) {
      break; /* Don't print if there is nothing but 0s in the buffer */
    }
    if(char_equivalents[i] == '\n') {
      printf("\\n\t\t");
    } else if (char_equivalents[i] == '\t') {
      printf("\\t\t");
    } else {
      printf("%d\t", (int)char_equivalents[i]); /* Print the ASCII character */
    }
  }
}

通过我之前的编辑Jonathan Leffler,我正在讨论如果自原始海报在评论中填写缓冲区后会发生什么:

  

我假设输入文件最多有1000个字符。

除非在一定数量的字符后面有换行符,否则输出将是非常长行。

我们可以拥有一个最大缓冲区为1000的数组,但我们也可以通过每x个字符数量处理文件来节省更多内存。在这里,在每NEW_TERMINAL_LINE个字符后,我们可以创建一个新行并打印出当前缓冲区。最后我们可以清空缓冲区,并继续处理字符。事实上,使用这种方法,缓冲区仅受计算机上可用内存的限制

假设我们希望一行上的最大字符数(以及相应的ASCII值)显示为10.文本文件包含字符串:random random random random random random random random [enter](假设字符串可能很多更长,程序仍然会整齐地显示它。该程序的输出类似于 1

r   a   n   d   o   m   [space] r   a   n   
114 97  110 100 111 109 32     114  97  110 

d   o   m   [space] r   a   n   d   o   m   
100 111 109 32     114  97  110 100 111 109 

[space] r   a   n   d   o   m   [space] r   a   
32     114  97  110 100 111 109 32     114  97  

n   d   o   m   [space] r   a   n   d   o   
110 100 111 109 32     114  97  110 100 111 

m   [space] r   a   n   d   o   m   [space] r   
109 32     114  97  110 100 111 109 32     114  

a   n   d   o   m   \n  
97  110 100 111 109 \n

如果NEW_TERMINAL_LINE设置为10

  1. 我们最终将ASCII等价物存储在名为char_equivalents的数组中。对于我们遇到的每个角色,我们将其存储在数组中,然后将其打印出来,然后打印一个标签。

  2. 一旦缓冲区数组已满,我们向下移动一条线,循环遍历数组,并使用格式打印出ASCII值:

    由于char基本上是伪装成int的ASCII,我们只需将char强制转换为int。这将打印出相应的ASCII值。然后,我们添加一个选项卡以确保所有内容与上面的行对齐。有了这些信息,循环数组并打印出相应的信息并不困难。

  3. 我们最后重置了缓冲区,并打印了NEW_TERMINAL_LINE字符后面看到的空行新行。

  4. 填充并重置缓冲区,直到我们打印完文件中的所有字符(重复前面的步骤)。

  5. 最后,有时缓冲区未满,所以我们从未打印出输出中最后一行的剩余ASCII等价物。我们只需再次致电print_current_characters()

  6. 1 我真的不认为这是格式化代码的最佳方式,但与此同时,我确实想要尊重original post要求的格式。

答案 1 :(得分:1)

如果您处理单个单词而不是每个字符,将会更方便。这样,您可以先打印单词的每个单独字符,然后打印下一个单词的每个字符的ASCII值。

你可以尝试这样的事情。

int main(int argc, char* argv[]) {
    FILE *fp;
    int c;
    char line[100];  /* Buffer to hold each line */
    fp = fopen(argv[1], "r");
    /* get each line, and print each word of the line */
    while (fgets(line, 100, fp) != NULL) {
            line[strlen(line) - 1] = '\0';
            print_words(line);
    }
    fclose(fp);
    return 0;
}

/* print_words: print each word from line */
void print_words(char *line)
{
    char *word;

    /* get each word, and print them with ascii values */
    if ((word = strtok(line, " ")) != NULL)
            ascii_print(word);
    while ((word = strtok(NULL, " ")) != NULL)
            ascii_print(word);
}

/* ascii_print: print each char and its ascii values for a word*/
void ascii_print(char *word)
{
    int i, len;

    len = strlen(word);

    /* print the word */
    for(i = 0; i < len; i++)
            printf("%-4c", word[i]);
    printf("\n");

    /* print ascii values */
    for(i = 0; i < len; i++)
            printf("%-4d", word[i]);
    printf("\n");
}

请注意,上述程序并不完全正确,并且可能会在某些测试用例中产生错误结果。然而,它表明,如果你逐字处理,而不是逐个字符地处理它会更容易。

虽然代码很简单,但如果您不熟悉,可能需要查看fgets()strtok()的手册页。

简单地说,fgets()从文件中获取linestrtok()从一行获取word。有关详细信息,您需要在Google中man 3 strtokman 3 fgets(如果使用类Unix机器,则在命令行中)。

答案 2 :(得分:0)

您可以先使用缓冲区将输入记录在一行中,然后通过将缓冲区中的字符传输到以下行中的整数来显示输入的ASCII值。